home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / posixmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  111.0 KB  |  4,830 lines

  1. /* POSIX module implementation */
  2.  
  3. /* This file is also used for Windows NT and MS-Win.  In that case the module
  4.    actually calls itself 'nt', not 'posix', and a few functions are
  5.    either unimplemented or implemented differently.  The source
  6.    assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
  7.    of the compiler used.  Different compilers define their own feature
  8.    test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
  9.  
  10. /* See also ../Dos/dosmodule.c */
  11.  
  12. static char posix__doc__ [] =
  13. "This module provides access to operating system functionality that is\n\
  14. standardized by the C Standard and the POSIX standard (a thinly\n\
  15. disguised Unix interface).  Refer to the library manual and\n\
  16. corresponding Unix manual entries for more information on calls.";
  17.  
  18. #include "Python.h"
  19.  
  20. #if defined(PYOS_OS2)
  21. #define  INCL_DOS
  22. #define  INCL_DOSERRORS
  23. #define  INCL_DOSPROCESS
  24. #define  INCL_NOPMAPI
  25. #include <os2.h>
  26. #endif
  27.  
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #ifdef HAVE_SYS_WAIT_H
  31. #include <sys/wait.h>        /* For WNOHANG */
  32. #endif
  33.  
  34. #ifdef HAVE_SIGNAL_H
  35. #include <signal.h>
  36. #endif
  37.  
  38. #include "mytime.h"        /* For clock_t on some systems */
  39.  
  40. #ifdef HAVE_FCNTL_H
  41. #include <fcntl.h>
  42. #endif /* HAVE_FCNTL_H */
  43.  
  44. /* Various compilers have only certain posix functions */
  45. /* XXX Gosh I wish these were all moved into config.h */
  46. #if defined(PYCC_VACPP) && defined(PYOS_OS2)
  47. #include <process.h>
  48. #else
  49. #if defined(__WATCOMC__) && !defined(__QNX__)        /* Watcom compiler */
  50. #define HAVE_GETCWD     1
  51. #define HAVE_OPENDIR    1
  52. #define HAVE_SYSTEM    1
  53. #if defined(__OS2__)
  54. #define HAVE_EXECV      1
  55. #define HAVE_WAIT       1
  56. #endif
  57. #include <process.h>
  58. #else
  59. #ifdef __BORLANDC__        /* Borland compiler */
  60. #define HAVE_EXECV      1
  61. #define HAVE_GETCWD     1
  62. #define HAVE_GETEGID    1
  63. #define HAVE_GETEUID    1
  64. #define HAVE_GETGID     1
  65. #define HAVE_GETPPID    1
  66. #define HAVE_GETUID     1
  67. #define HAVE_KILL       1
  68. #define HAVE_OPENDIR    1
  69. #define HAVE_PIPE       1
  70. #define HAVE_POPEN      1
  71. #define HAVE_SYSTEM    1
  72. #define HAVE_WAIT       1
  73. #else
  74. #ifdef _MSC_VER        /* Microsoft compiler */
  75. #define HAVE_GETCWD     1
  76. #ifdef MS_WIN32
  77. #define HAVE_SPAWNV    1
  78. #define HAVE_EXECV      1
  79. #define HAVE_PIPE       1
  80. #define HAVE_POPEN      1
  81. #define HAVE_SYSTEM    1
  82. #else /* 16-bit Windows */
  83. #endif /* !MS_WIN32 */
  84. #else            /* all other compilers */
  85. /* Unix functions that the configure script doesn't check for */
  86. #define HAVE_EXECV      1
  87. #define HAVE_FORK       1
  88. #define HAVE_GETCWD     1
  89. #define HAVE_GETEGID    1
  90. #define HAVE_GETEUID    1
  91. #define HAVE_GETGID     1
  92. #define HAVE_GETPPID    1
  93. #define HAVE_GETUID     1
  94. #define HAVE_KILL       1
  95. #define HAVE_OPENDIR    1
  96. #define HAVE_PIPE       1
  97. #define HAVE_POPEN      1
  98. #define HAVE_SYSTEM    1
  99. #define HAVE_WAIT       1
  100. #define HAVE_TTYNAME    1
  101. #endif  /* _MSC_VER */
  102. #endif  /* __BORLANDC__ */
  103. #endif  /* ! __WATCOMC__ || __QNX__ */
  104. #endif /* ! __IBMC__ */
  105.  
  106. #ifndef _MSC_VER
  107.  
  108. #ifdef HAVE_UNISTD_H
  109. #include <unistd.h>
  110. #endif
  111.  
  112. #ifdef NeXT
  113. /* NeXT's <unistd.h> and <utime.h> aren't worth much */
  114. #undef HAVE_UNISTD_H
  115. #undef HAVE_UTIME_H
  116. #define HAVE_WAITPID
  117. /* #undef HAVE_GETCWD */
  118. #define UNION_WAIT /* This should really be checked for by autoconf */
  119. #endif
  120.  
  121. #ifdef HAVE_UNISTD_H
  122. /* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
  123. extern int rename();
  124. extern int pclose();
  125. extern int lstat();
  126. extern int symlink();
  127. extern int fsync();
  128. #else /* !HAVE_UNISTD_H */
  129. #if defined(PYCC_VACPP)
  130. extern int mkdir Py_PROTO((char *));
  131. #else
  132. #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
  133. extern int mkdir Py_PROTO((const char *));
  134. #else
  135. extern int mkdir Py_PROTO((const char *, mode_t));
  136. #endif
  137. #endif
  138. #if defined(__IBMC__) || defined(__IBMCPP__)
  139. extern int chdir Py_PROTO((char *));
  140. extern int rmdir Py_PROTO((char *));
  141. #else
  142. extern int chdir Py_PROTO((const char *));
  143. extern int rmdir Py_PROTO((const char *));
  144. #endif
  145. extern int chmod Py_PROTO((const char *, mode_t));
  146. extern int chown Py_PROTO((const char *, uid_t, gid_t));
  147. extern char *getcwd Py_PROTO((char *, int));
  148. extern char *strerror Py_PROTO((int));
  149. extern int link Py_PROTO((const char *, const char *));
  150. extern int rename Py_PROTO((const char *, const char *));
  151. extern int stat Py_PROTO((const char *, struct stat *));
  152. extern int unlink Py_PROTO((const char *));
  153. extern int pclose Py_PROTO((FILE *));
  154. #ifdef HAVE_SYMLINK
  155. extern int symlink Py_PROTO((const char *, const char *));
  156. #endif /* HAVE_SYMLINK */
  157. #ifdef HAVE_LSTAT
  158. extern int lstat Py_PROTO((const char *, struct stat *));
  159. #endif /* HAVE_LSTAT */
  160. #endif /* !HAVE_UNISTD_H */
  161.  
  162. #endif /* !_MSC_VER */
  163.  
  164. #ifdef HAVE_UTIME_H
  165. #include <utime.h>
  166. #endif /* HAVE_UTIME_H */
  167.  
  168. #ifdef HAVE_SYS_UTIME_H
  169. #include <sys/utime.h>
  170. #define HAVE_UTIME_H /* pretend we do for the rest of this file */
  171. #endif /* HAVE_SYS_UTIME_H */
  172.  
  173. #ifdef HAVE_SYS_TIMES_H
  174. #include <sys/times.h>
  175. #endif /* HAVE_SYS_TIMES_H */
  176.  
  177. #ifdef HAVE_SYS_PARAM_H
  178. #include <sys/param.h>
  179. #endif /* HAVE_SYS_PARAM_H */
  180.  
  181. #ifdef HAVE_SYS_UTSNAME_H
  182. #include <sys/utsname.h>
  183. #endif /* HAVE_SYS_UTSNAME_H */
  184.  
  185. #ifndef MAXPATHLEN
  186. #define MAXPATHLEN 1024
  187. #endif /* MAXPATHLEN */
  188.  
  189. #ifdef HAVE_DIRENT_H
  190. #include <dirent.h>
  191. #define NAMLEN(dirent) strlen((dirent)->d_name)
  192. #else
  193. #if defined(__WATCOMC__) && !defined(__QNX__)
  194. #include <direct.h>
  195. #define NAMLEN(dirent) strlen((dirent)->d_name)
  196. #else
  197. #define dirent direct
  198. #define NAMLEN(dirent) (dirent)->d_namlen
  199. #endif
  200. #ifdef HAVE_SYS_NDIR_H
  201. #include <sys/ndir.h>
  202. #endif
  203. #ifdef HAVE_SYS_DIR_H
  204. #include <sys/dir.h>
  205. #endif
  206. #ifdef HAVE_NDIR_H
  207. #include <ndir.h>
  208. #endif
  209. #endif
  210.  
  211. #ifdef _MSC_VER
  212. #include <direct.h>
  213. #include <io.h>
  214. #include <process.h>
  215. #include <windows.h>
  216. #ifdef MS_WIN32
  217. #define popen    _popen
  218. #define pclose    _pclose
  219. #else /* 16-bit Windows */
  220. #include <dos.h>
  221. #include <ctype.h>
  222. #endif /* MS_WIN32 */
  223. #endif /* _MSC_VER */
  224.  
  225. #if defined(PYCC_VACPP) && defined(PYOS_OS2)
  226. #include <io.h>
  227. #endif /* OS2 */
  228.  
  229. #ifdef UNION_WAIT
  230. /* Emulate some macros on systems that have a union instead of macros */
  231.  
  232. #ifndef WIFEXITED
  233. #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
  234. #endif
  235.  
  236. #ifndef WEXITSTATUS
  237. #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
  238. #endif
  239.  
  240. #ifndef WTERMSIG
  241. #define WTERMSIG(u_wait) ((u_wait).w_termsig)
  242. #endif
  243.  
  244. #endif /* UNION_WAIT */
  245.  
  246. /* Don't use the "_r" form if we don't need it (also, won't have a
  247.    prototype for it, at least on Solaris -- maybe others as well?). */
  248. #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
  249. #define USE_CTERMID_R
  250. #endif
  251.  
  252. #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
  253. #define USE_TMPNAM_R
  254. #endif
  255.  
  256. /* Return a dictionary corresponding to the POSIX environment table */
  257.  
  258. #if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
  259. extern char **environ;
  260. #endif /* !_MSC_VER */
  261.  
  262. static PyObject *
  263. convertenviron()
  264. {
  265.     PyObject *d;
  266.     char **e;
  267.     d = PyDict_New();
  268.     if (d == NULL)
  269.         return NULL;
  270.     if (environ == NULL)
  271.         return d;
  272.     /* This part ignores errors */
  273.     for (e = environ; *e != NULL; e++) {
  274.         PyObject *k;
  275.         PyObject *v;
  276.         char *p = strchr(*e, '=');
  277.         if (p == NULL)
  278.             continue;
  279.         k = PyString_FromStringAndSize(*e, (int)(p-*e));
  280.         if (k == NULL) {
  281.             PyErr_Clear();
  282.             continue;
  283.         }
  284.         v = PyString_FromString(p+1);
  285.         if (v == NULL) {
  286.             PyErr_Clear();
  287.             Py_DECREF(k);
  288.             continue;
  289.         }
  290.         if (PyDict_GetItem(d, k) == NULL) {
  291.             if (PyDict_SetItem(d, k, v) != 0)
  292.                 PyErr_Clear();
  293.         }
  294.         Py_DECREF(k);
  295.         Py_DECREF(v);
  296.     }
  297. #if defined(PYOS_OS2)
  298.     {
  299.         APIRET rc;
  300.         char   buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
  301.  
  302.         rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
  303.         if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
  304.             PyObject *v = PyString_FromString(buffer);
  305.             PyDict_SetItemString(d, "BEGINLIBPATH", v);
  306.             Py_DECREF(v);
  307.         }
  308.         rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
  309.         if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
  310.             PyObject *v = PyString_FromString(buffer);
  311.             PyDict_SetItemString(d, "ENDLIBPATH", v);
  312.             Py_DECREF(v);
  313.         }
  314.     }
  315. #endif
  316.     return d;
  317. }
  318.  
  319.  
  320. /* Set a POSIX-specific error from errno, and return NULL */
  321.  
  322. static PyObject *
  323. posix_error()
  324. {
  325.     return PyErr_SetFromErrno(PyExc_OSError);
  326. }
  327. static PyObject *
  328. posix_error_with_filename(name)
  329.     char* name;
  330. {
  331.     return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
  332. }
  333.  
  334.  
  335. #if defined(PYOS_OS2)
  336. /**********************************************************************
  337.  *         Helper Function to Trim and Format OS/2 Messages
  338.  **********************************************************************/
  339.     static void
  340. os2_formatmsg(char *msgbuf, int msglen, char *reason)
  341. {
  342.     msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
  343.  
  344.     if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
  345.         char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
  346.  
  347.         while (lastc > msgbuf && isspace(*lastc))
  348.             *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
  349.     }
  350.  
  351.     /* Add Optional Reason Text */
  352.     if (reason) {
  353.         strcat(msgbuf, " : ");
  354.         strcat(msgbuf, reason);
  355.     }
  356. }
  357.  
  358. /**********************************************************************
  359.  *             Decode an OS/2 Operating System Error Code
  360.  *
  361.  * A convenience function to lookup an OS/2 error code and return a
  362.  * text message we can use to raise a Python exception.
  363.  *
  364.  * Notes:
  365.  *   The messages for errors returned from the OS/2 kernel reside in
  366.  *   the file OSO001.MSG in the \OS2 directory hierarchy.
  367.  *
  368.  **********************************************************************/
  369.     static char *
  370. os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
  371. {
  372.     APIRET rc;
  373.     ULONG  msglen;
  374.  
  375.     /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
  376.     Py_BEGIN_ALLOW_THREADS
  377.     rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
  378.                        errorcode, "oso001.msg", &msglen);
  379.     Py_END_ALLOW_THREADS
  380.  
  381.     if (rc == NO_ERROR)
  382.         os2_formatmsg(msgbuf, msglen, reason);
  383.     else
  384.         sprintf(msgbuf, "unknown OS error #%d", errorcode);
  385.  
  386.     return msgbuf;
  387. }
  388.  
  389. /* Set an OS/2-specific error and return NULL.  OS/2 kernel
  390.    errors are not in a global variable e.g. 'errno' nor are
  391.    they congruent with posix error numbers. */
  392.  
  393. static PyObject * os2_error(int code)
  394. {
  395.     char text[1024];
  396.     PyObject *v;
  397.  
  398.     os2_strerror(text, sizeof(text), code, "");
  399.  
  400.     v = Py_BuildValue("(is)", code, text);
  401.     if (v != NULL) {
  402.         PyErr_SetObject(PyExc_OSError, v);
  403.         Py_DECREF(v);
  404.     }
  405.     return NULL; /* Signal to Python that an Exception is Pending */
  406. }
  407.  
  408. #endif /* OS2 */
  409.  
  410. /* POSIX generic methods */
  411.  
  412. static PyObject *
  413. posix_int(args, format, func)
  414.         PyObject *args;
  415.         char *format;
  416.     int (*func) Py_FPROTO((int));
  417. {
  418.     int fd;
  419.     int res;
  420.     if (!PyArg_ParseTuple(args,  format, &fd))
  421.         return NULL;
  422.     Py_BEGIN_ALLOW_THREADS
  423.     res = (*func)(fd);
  424.     Py_END_ALLOW_THREADS
  425.     if (res < 0)
  426.         return posix_error();
  427.     Py_INCREF(Py_None);
  428.     return Py_None;
  429. }
  430.  
  431.  
  432. static PyObject *
  433. posix_1str(args, format, func)
  434.     PyObject *args;
  435.         char *format;
  436.     int (*func) Py_FPROTO((const char *));
  437. {
  438.     char *path1;
  439.     int res;
  440.     if (!PyArg_ParseTuple(args, format, &path1))
  441.         return NULL;
  442.     Py_BEGIN_ALLOW_THREADS
  443.     res = (*func)(path1);
  444.     Py_END_ALLOW_THREADS
  445.     if (res < 0)
  446.         return posix_error_with_filename(path1);
  447.     Py_INCREF(Py_None);
  448.     return Py_None;
  449. }
  450.  
  451. static PyObject *
  452. posix_2str(args, format, func)
  453.     PyObject *args;
  454.         char *format;
  455.     int (*func) Py_FPROTO((const char *, const char *));
  456. {
  457.     char *path1, *path2;
  458.     int res;
  459.     if (!PyArg_ParseTuple(args, format, &path1, &path2))
  460.         return NULL;
  461.     Py_BEGIN_ALLOW_THREADS
  462.     res = (*func)(path1, path2);
  463.     Py_END_ALLOW_THREADS
  464.     if (res != 0)
  465.         /* XXX how to report both path1 and path2??? */
  466.         return posix_error();
  467.     Py_INCREF(Py_None);
  468.     return Py_None;
  469. }
  470.  
  471. static PyObject *
  472. posix_strint(args, format, func)
  473.     PyObject *args;
  474.         char *format;
  475.     int (*func) Py_FPROTO((const char *, int));
  476. {
  477.     char *path;
  478.     int i;
  479.     int res;
  480.     if (!PyArg_ParseTuple(args, format, &path, &i))
  481.         return NULL;
  482.     Py_BEGIN_ALLOW_THREADS
  483.     res = (*func)(path, i);
  484.     Py_END_ALLOW_THREADS
  485.     if (res < 0)
  486.         return posix_error_with_filename(path);
  487.     Py_INCREF(Py_None);
  488.     return Py_None;
  489. }
  490.  
  491. static PyObject *
  492. posix_strintint(args, format, func)
  493.     PyObject *args;
  494.         char *format;
  495.     int (*func) Py_FPROTO((const char *, int, int));
  496. {
  497.     char *path;
  498.     int i,i2;
  499.     int res;
  500.     if (!PyArg_ParseTuple(args, format, &path, &i, &i2))
  501.         return NULL;
  502.     Py_BEGIN_ALLOW_THREADS
  503.     res = (*func)(path, i, i2);
  504.     Py_END_ALLOW_THREADS
  505.     if (res < 0)
  506.         return posix_error_with_filename(path);
  507.     Py_INCREF(Py_None);
  508.     return Py_None;
  509. }
  510.  
  511. static PyObject *
  512. posix_do_stat(self, args, format, statfunc)
  513.     PyObject *self;
  514.     PyObject *args;
  515.         char *format;
  516.     int (*statfunc) Py_FPROTO((const char *, struct stat *));
  517. {
  518.     struct stat st;
  519.     char *path;
  520.     int res;
  521.  
  522. #ifdef MS_WIN32
  523.       int pathlen;
  524.       char pathcopy[MAX_PATH];
  525. #endif /* MS_WIN32 */
  526.  
  527.     if (!PyArg_ParseTuple(args, format, &path))
  528.         return NULL;
  529.  
  530. #ifdef MS_WIN32
  531.     pathlen = strlen(path);
  532.     /* the library call can blow up if the file name is too long! */
  533.     if (pathlen > MAX_PATH) {
  534.         errno = ENAMETOOLONG;
  535.         return posix_error();
  536.     }
  537.  
  538.     if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
  539.         /* exception for specific or current drive root */
  540.         if (!((pathlen == 1) ||
  541.               ((pathlen == 3) &&
  542.               (path[1] == ':') &&
  543.               (path[2] == '\\' || path[2] == '/'))))
  544.         {
  545.             strncpy(pathcopy, path, pathlen);
  546.             pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
  547.             path = pathcopy;
  548.         }
  549.     }
  550. #endif /* MS_WIN32 */
  551.  
  552.     Py_BEGIN_ALLOW_THREADS
  553.     res = (*statfunc)(path, &st);
  554.     Py_END_ALLOW_THREADS
  555.     if (res != 0)
  556.         return posix_error_with_filename(path);
  557. #if !defined(HAVE_LARGEFILE_SUPPORT)
  558.     return Py_BuildValue("(llllllllll)",
  559.                  (long)st.st_mode,
  560.                  (long)st.st_ino,
  561.                  (long)st.st_dev,
  562.                  (long)st.st_nlink,
  563.                  (long)st.st_uid,
  564.                  (long)st.st_gid,
  565.                  (long)st.st_size,
  566.                  (long)st.st_atime,
  567.                  (long)st.st_mtime,
  568.                  (long)st.st_ctime);
  569. #else
  570.     return Py_BuildValue("(lLllllLlll)",
  571.                  (long)st.st_mode,
  572.                  (LONG_LONG)st.st_ino,
  573.                  (long)st.st_dev,
  574.                  (long)st.st_nlink,
  575.                  (long)st.st_uid,
  576.                  (long)st.st_gid,
  577.                  (LONG_LONG)st.st_size,
  578.                  (long)st.st_atime,
  579.                  (long)st.st_mtime,
  580.                  (long)st.st_ctime);
  581. #endif
  582. }
  583.  
  584.  
  585. /* POSIX methods */
  586.  
  587. static char posix_access__doc__[] =
  588. "access(path, mode) -> 1 if granted, 0 otherwise\n\
  589. Test for access to a file.";
  590.  
  591. static PyObject *
  592. posix_access(self, args)
  593.     PyObject *self;
  594.     PyObject *args;
  595. {
  596.     char *path;
  597.     int mode;
  598.     int res;
  599.  
  600.     if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
  601.         return NULL;
  602.     Py_BEGIN_ALLOW_THREADS
  603.     res = access(path, mode);
  604.     Py_END_ALLOW_THREADS
  605.     return(PyInt_FromLong(res == 0 ? 1L : 0L));
  606. }
  607.  
  608. #ifndef F_OK
  609. #define F_OK 0
  610. #endif
  611. #ifndef R_OK
  612. #define R_OK 4
  613. #endif
  614. #ifndef W_OK
  615. #define W_OK 2
  616. #endif
  617. #ifndef X_OK
  618. #define X_OK 1
  619. #endif
  620.  
  621. #ifdef HAVE_TTYNAME
  622. static char posix_ttyname__doc__[] =
  623. "ttyname(fd) -> String\n\
  624. Return the name of the terminal device connected to 'fd'.";
  625.  
  626. static PyObject *
  627. posix_ttyname(self, args)
  628.     PyObject *self;
  629.     PyObject *args;
  630. {
  631.     int id;
  632.     char *ret;
  633.  
  634.     if (!PyArg_ParseTuple(args, "i:ttyname", &id))
  635.         return NULL;
  636.  
  637.     ret = ttyname(id);
  638.     if (ret == NULL)
  639.         return(posix_error());
  640.     return(PyString_FromString(ret));
  641. }
  642. #endif
  643.  
  644. #ifdef HAVE_CTERMID
  645. static char posix_ctermid__doc__[] =
  646. "ctermid() -> String\n\
  647. Return the name of the controlling terminal for this process.";
  648.  
  649. static PyObject *
  650. posix_ctermid(self, args)
  651.     PyObject *self;
  652.     PyObject *args;
  653. {
  654.         char *ret;
  655.         char buffer[L_ctermid];
  656.  
  657.     if (!PyArg_ParseTuple(args, ":ctermid"))
  658.         return NULL;
  659.  
  660. #ifdef USE_CTERMID_R
  661.     ret = ctermid_r(buffer);
  662. #else
  663.         ret = ctermid(buffer);
  664. #endif
  665.     if (ret == NULL)
  666.         return(posix_error());
  667.     return(PyString_FromString(buffer));
  668. }
  669. #endif
  670.  
  671. static char posix_chdir__doc__[] =
  672. "chdir(path) -> None\n\
  673. Change the current working directory to the specified path.";
  674.  
  675. static PyObject *
  676. posix_chdir(self, args)
  677.     PyObject *self;
  678.     PyObject *args;
  679. {
  680.     return posix_1str(args, "s:chdir", chdir);
  681. }
  682.  
  683.  
  684. static char posix_chmod__doc__[] =
  685. "chmod(path, mode) -> None\n\
  686. Change the access permissions of a file.";
  687.  
  688. static PyObject *
  689. posix_chmod(self, args)
  690.     PyObject *self;
  691.     PyObject *args;
  692. {
  693.     char *path;
  694.     int i;
  695.     int res;
  696.     if (!PyArg_ParseTuple(args, "si", &path, &i))
  697.         return NULL;
  698.     Py_BEGIN_ALLOW_THREADS
  699.     res = chmod(path, i);
  700.     Py_END_ALLOW_THREADS
  701.     if (res < 0)
  702.         return posix_error_with_filename(path);
  703.     Py_INCREF(Py_None);
  704.     return Py_None;
  705. }
  706.  
  707.  
  708. #ifdef HAVE_FSYNC
  709. static char posix_fsync__doc__[] =
  710. "fsync(fildes) -> None\n\
  711. force write of file with filedescriptor to disk.";
  712.  
  713. static PyObject *
  714. posix_fsync(self, args)
  715.        PyObject *self;
  716.        PyObject *args;
  717. {
  718.        return posix_int(args, "i:fsync", fsync);
  719. }
  720. #endif /* HAVE_FSYNC */
  721.  
  722. #ifdef HAVE_FDATASYNC
  723. static char posix_fdatasync__doc__[] =
  724. "fdatasync(fildes) -> None\n\
  725. force write of file with filedescriptor to disk.\n\
  726.  does not force update of metadata.";
  727.  
  728. extern int fdatasync(int); /* Prototype just in case */
  729.  
  730. static PyObject *
  731. posix_fdatasync(self, args)
  732.        PyObject *self;
  733.        PyObject *args;
  734. {
  735.        return posix_int(args, "i:fdatasync", fdatasync);
  736. }
  737. #endif /* HAVE_FDATASYNC */
  738.  
  739.  
  740. #ifdef HAVE_CHOWN
  741. static char posix_chown__doc__[] =
  742. "chown(path, uid, gid) -> None\n\
  743. Change the owner and group id of path to the numeric uid and gid.";
  744.  
  745. static PyObject *
  746. posix_chown(self, args)
  747.     PyObject *self;
  748.     PyObject *args;
  749. {
  750.     return posix_strintint(args, "sii:chown", chown);
  751. }
  752. #endif /* HAVE_CHOWN */
  753.  
  754.  
  755. #ifdef HAVE_GETCWD
  756. static char posix_getcwd__doc__[] =
  757. "getcwd() -> path\n\
  758. Return a string representing the current working directory.";
  759.  
  760. static PyObject *
  761. posix_getcwd(self, args)
  762.     PyObject *self;
  763.     PyObject *args;
  764. {
  765.     char buf[1026];
  766.     char *res;
  767.     if (!PyArg_ParseTuple(args, ":getcwd"))
  768.         return NULL;
  769.     Py_BEGIN_ALLOW_THREADS
  770.     res = getcwd(buf, sizeof buf);
  771.     Py_END_ALLOW_THREADS
  772.     if (res == NULL)
  773.         return posix_error();
  774.     return PyString_FromString(buf);
  775. }
  776. #endif
  777.  
  778.  
  779. #ifdef HAVE_LINK
  780. static char posix_link__doc__[] =
  781. "link(src, dst) -> None\n\
  782. Create a hard link to a file.";
  783.  
  784. static PyObject *
  785. posix_link(self, args)
  786.     PyObject *self;
  787.     PyObject *args;
  788. {
  789.     return posix_2str(args, "ss:link", link);
  790. }
  791. #endif /* HAVE_LINK */
  792.  
  793.  
  794. static char posix_listdir__doc__[] =
  795. "listdir(path) -> list_of_strings\n\
  796. Return a list containing the names of the entries in the directory.\n\
  797. \n\
  798.     path: path of directory to list\n\
  799. \n\
  800. The list is in arbitrary order.  It does not include the special\n\
  801. entries '.' and '..' even if they are present in the directory.";
  802.  
  803. static PyObject *
  804. posix_listdir(self, args)
  805.     PyObject *self;
  806.     PyObject *args;
  807. {
  808.     /* XXX Should redo this putting the (now four) versions of opendir
  809.        in separate files instead of having them all here... */
  810. #if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
  811.  
  812.     char *name;
  813.     int len;
  814.     PyObject *d, *v;
  815.     HANDLE hFindFile;
  816.     WIN32_FIND_DATA FileData;
  817.     char namebuf[MAX_PATH+5];
  818.  
  819.     if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
  820.         return NULL;
  821.     if (len >= MAX_PATH) {
  822.         PyErr_SetString(PyExc_ValueError, "path too long");
  823.         return NULL;
  824.     }
  825.     strcpy(namebuf, name);
  826.     if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
  827.         namebuf[len++] = '/';
  828.     strcpy(namebuf + len, "*.*");
  829.  
  830.     if ((d = PyList_New(0)) == NULL)
  831.         return NULL;
  832.  
  833.     hFindFile = FindFirstFile(namebuf, &FileData);
  834.     if (hFindFile == INVALID_HANDLE_VALUE) {
  835.         errno = GetLastError();
  836.         if (errno == ERROR_FILE_NOT_FOUND)
  837.             return PyList_New(0);
  838.         return posix_error_with_filename(name);
  839.     }
  840.     do {
  841.         if (FileData.cFileName[0] == '.' &&
  842.             (FileData.cFileName[1] == '\0' ||
  843.              FileData.cFileName[1] == '.' &&
  844.              FileData.cFileName[2] == '\0'))
  845.             continue;
  846.         v = PyString_FromString(FileData.cFileName);
  847.         if (v == NULL) {
  848.             Py_DECREF(d);
  849.             d = NULL;
  850.             break;
  851.         }
  852.         if (PyList_Append(d, v) != 0) {
  853.             Py_DECREF(v);
  854.             Py_DECREF(d);
  855.             d = NULL;
  856.             break;
  857.         }
  858.         Py_DECREF(v);
  859.     } while (FindNextFile(hFindFile, &FileData) == TRUE);
  860.  
  861.     if (FindClose(hFindFile) == FALSE) {
  862.         errno = GetLastError();
  863.         return posix_error_with_filename(&name);
  864.     }
  865.  
  866.     return d;
  867.  
  868. #else /* !MS_WIN32 */
  869. #ifdef _MSC_VER /* 16-bit Windows */
  870.  
  871. #ifndef MAX_PATH
  872. #define MAX_PATH    250
  873. #endif
  874.     char *name, *pt;
  875.     int len;
  876.     PyObject *d, *v;
  877.     char namebuf[MAX_PATH+5];
  878.     struct _find_t ep;
  879.  
  880.     if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
  881.         return NULL;
  882.     if (len >= MAX_PATH) {
  883.         PyErr_SetString(PyExc_ValueError, "path too long");
  884.         return NULL;
  885.     }
  886.     strcpy(namebuf, name);
  887.     for (pt = namebuf; *pt; pt++)
  888.         if (*pt == '/')
  889.             *pt = '\\';
  890.     if (namebuf[len-1] != '\\')
  891.         namebuf[len++] = '\\';
  892.     strcpy(namebuf + len, "*.*");
  893.  
  894.     if ((d = PyList_New(0)) == NULL)
  895.         return NULL;
  896.  
  897.     if (_dos_findfirst(namebuf, _A_RDONLY |
  898.                _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
  899.         {
  900.         errno = ENOENT;
  901.         return posix_error_with_filename(name);
  902.     }
  903.     do {
  904.         if (ep.name[0] == '.' &&
  905.             (ep.name[1] == '\0' ||
  906.              ep.name[1] == '.' &&
  907.              ep.name[2] == '\0'))
  908.             continue;
  909.         strcpy(namebuf, ep.name);
  910.         for (pt = namebuf; *pt; pt++)
  911.             if (isupper(*pt))
  912.                 *pt = tolower(*pt);
  913.         v = PyString_FromString(namebuf);
  914.         if (v == NULL) {
  915.             Py_DECREF(d);
  916.             d = NULL;
  917.             break;
  918.         }
  919.         if (PyList_Append(d, v) != 0) {
  920.             Py_DECREF(v);
  921.             Py_DECREF(d);
  922.             d = NULL;
  923.             break;
  924.         }
  925.         Py_DECREF(v);
  926.     } while (_dos_findnext(&ep) == 0);
  927.  
  928.     return d;
  929.  
  930. #else
  931. #if defined(PYOS_OS2)
  932.  
  933. #ifndef MAX_PATH
  934. #define MAX_PATH    CCHMAXPATH
  935. #endif
  936.     char *name, *pt;
  937.     int len;
  938.     PyObject *d, *v;
  939.     char namebuf[MAX_PATH+5];
  940.     HDIR  hdir = 1;
  941.     ULONG srchcnt = 1;
  942.     FILEFINDBUF3   ep;
  943.     APIRET rc;
  944.  
  945.     if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
  946.         return NULL;
  947.     if (len >= MAX_PATH) {
  948.         PyErr_SetString(PyExc_ValueError, "path too long");
  949.         return NULL;
  950.     }
  951.     strcpy(namebuf, name);
  952.     for (pt = namebuf; *pt; pt++)
  953.         if (*pt == '/')
  954.             *pt = '\\';
  955.     if (namebuf[len-1] != '\\')
  956.         namebuf[len++] = '\\';
  957.     strcpy(namebuf + len, "*.*");
  958.  
  959.     if ((d = PyList_New(0)) == NULL)
  960.         return NULL;
  961.  
  962.     rc = DosFindFirst(namebuf,         /* Wildcard Pattern to Match */
  963.                       &hdir,           /* Handle to Use While Search Directory */
  964.                       FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
  965.                       &ep, sizeof(ep), /* Structure to Receive Directory Entry */
  966.                       &srchcnt,        /* Max and Actual Count of Entries Per Iteration */
  967.                       FIL_STANDARD);   /* Format of Entry (EAs or Not) */
  968.  
  969.     if (rc != NO_ERROR) {
  970.         errno = ENOENT;
  971.         return posix_error_with_filename(name);
  972.     }
  973.  
  974.     if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
  975.         do {
  976.             if (ep.achName[0] == '.'
  977.             && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
  978.                 continue; /* Skip Over "." and ".." Names */
  979.  
  980.             strcpy(namebuf, ep.achName);
  981.  
  982.             /* Leave Case of Name Alone -- In Native Form */
  983.             /* (Removed Forced Lowercasing Code) */
  984.  
  985.             v = PyString_FromString(namebuf);
  986.             if (v == NULL) {
  987.                 Py_DECREF(d);
  988.                 d = NULL;
  989.                 break;
  990.             }
  991.             if (PyList_Append(d, v) != 0) {
  992.                 Py_DECREF(v);
  993.                 Py_DECREF(d);
  994.                 d = NULL;
  995.                 break;
  996.             }
  997.             Py_DECREF(v);
  998.         } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
  999.     }
  1000.  
  1001.     return d;
  1002. #else
  1003.  
  1004.     char *name;
  1005.     PyObject *d, *v;
  1006.     DIR *dirp;
  1007.     struct dirent *ep;
  1008.     if (!PyArg_ParseTuple(args, "s:listdir", &name))
  1009.         return NULL;
  1010.     if ((dirp = opendir(name)) == NULL) {
  1011.         return posix_error_with_filename(name);
  1012.     }
  1013.     if ((d = PyList_New(0)) == NULL) {
  1014.         closedir(dirp);
  1015.         return NULL;
  1016.     }
  1017.     while ((ep = readdir(dirp)) != NULL) {
  1018.         if (ep->d_name[0] == '.' &&
  1019.             (NAMLEN(ep) == 1 ||
  1020.              (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
  1021.             continue;
  1022.         v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
  1023.         if (v == NULL) {
  1024.             Py_DECREF(d);
  1025.             d = NULL;
  1026.             break;
  1027.         }
  1028.         if (PyList_Append(d, v) != 0) {
  1029.             Py_DECREF(v);
  1030.             Py_DECREF(d);
  1031.             d = NULL;
  1032.             break;
  1033.         }
  1034.         Py_DECREF(v);
  1035.     }
  1036.     closedir(dirp);
  1037.  
  1038.     return d;
  1039.  
  1040. #endif /* !PYOS_OS2 */
  1041. #endif /* !_MSC_VER */
  1042. #endif /* !MS_WIN32 */
  1043. }
  1044.  
  1045. static char posix_mkdir__doc__[] =
  1046. "mkdir(path [, mode=0777]) -> None\n\
  1047. Create a directory.";
  1048.  
  1049. static PyObject *
  1050. posix_mkdir(self, args)
  1051.     PyObject *self;
  1052.     PyObject *args;
  1053. {
  1054.     int res;
  1055.     char *path;
  1056.     int mode = 0777;
  1057.     if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
  1058.         return NULL;
  1059.     Py_BEGIN_ALLOW_THREADS
  1060. #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
  1061.     res = mkdir(path);
  1062. #else
  1063.     res = mkdir(path, mode);
  1064. #endif
  1065.     Py_END_ALLOW_THREADS
  1066.     if (res < 0)
  1067.         return posix_error_with_filename(path);
  1068.     Py_INCREF(Py_None);
  1069.     return Py_None;
  1070. }
  1071.  
  1072.  
  1073. #ifdef HAVE_NICE
  1074. static char posix_nice__doc__[] =
  1075. "nice(inc) -> new_priority\n\
  1076. Decrease the priority of process and return new priority.";
  1077.  
  1078. static PyObject *
  1079. posix_nice(self, args)
  1080.     PyObject *self;
  1081.     PyObject *args;
  1082. {
  1083.     int increment, value;
  1084.  
  1085.     if (!PyArg_ParseTuple(args, "i:nice", &increment))
  1086.         return NULL;
  1087.     value = nice(increment);
  1088.     if (value == -1)
  1089.         return posix_error();
  1090.     return PyInt_FromLong((long) value);
  1091. }
  1092. #endif /* HAVE_NICE */
  1093.  
  1094.  
  1095. static char posix_rename__doc__[] =
  1096. "rename(old, new) -> None\n\
  1097. Rename a file or directory.";
  1098.  
  1099. static PyObject *
  1100. posix_rename(self, args)
  1101.     PyObject *self;
  1102.     PyObject *args;
  1103. {
  1104.     return posix_2str(args, "ss:rename", rename);
  1105. }
  1106.  
  1107.  
  1108. static char posix_rmdir__doc__[] =
  1109. "rmdir(path) -> None\n\
  1110. Remove a directory.";
  1111.  
  1112. static PyObject *
  1113. posix_rmdir(self, args)
  1114.     PyObject *self;
  1115.     PyObject *args;
  1116. {
  1117.     return posix_1str(args, "s:rmdir", rmdir);
  1118. }
  1119.  
  1120.  
  1121. static char posix_stat__doc__[] =
  1122. "stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
  1123. Perform a stat system call on the given path.";
  1124.  
  1125. static PyObject *
  1126. posix_stat(self, args)
  1127.     PyObject *self;
  1128.     PyObject *args;
  1129. {
  1130.     return posix_do_stat(self, args, "s:stat", stat);
  1131. }
  1132.  
  1133.  
  1134. #ifdef HAVE_SYSTEM
  1135. static char posix_system__doc__[] =
  1136. "system(command) -> exit_status\n\
  1137. Execute the command (a string) in a subshell.";
  1138.  
  1139. static PyObject *
  1140. posix_system(self, args)
  1141.     PyObject *self;
  1142.     PyObject *args;
  1143. {
  1144.     char *command;
  1145.     long sts;
  1146.     if (!PyArg_ParseTuple(args, "s:system", &command))
  1147.         return NULL;
  1148.     Py_BEGIN_ALLOW_THREADS
  1149.     sts = system(command);
  1150.     Py_END_ALLOW_THREADS
  1151.     return PyInt_FromLong(sts);
  1152. }
  1153. #endif
  1154.  
  1155.  
  1156. static char posix_umask__doc__[] =
  1157. "umask(new_mask) -> old_mask\n\
  1158. Set the current numeric umask and return the previous umask.";
  1159.  
  1160. static PyObject *
  1161. posix_umask(self, args)
  1162.     PyObject *self;
  1163.     PyObject *args;
  1164. {
  1165.     int i;
  1166.     if (!PyArg_ParseTuple(args, "i:umask", &i))
  1167.         return NULL;
  1168.     i = umask(i);
  1169.     if (i < 0)
  1170.         return posix_error();
  1171.     return PyInt_FromLong((long)i);
  1172. }
  1173.  
  1174.  
  1175. static char posix_unlink__doc__[] =
  1176. "unlink(path) -> None\n\
  1177. Remove a file (same as remove(path)).";
  1178.  
  1179. static char posix_remove__doc__[] =
  1180. "remove(path) -> None\n\
  1181. Remove a file (same as unlink(path)).";
  1182.  
  1183. static PyObject *
  1184. posix_unlink(self, args)
  1185.     PyObject *self;
  1186.     PyObject *args;
  1187. {
  1188.     return posix_1str(args, "s:remove", unlink);
  1189. }
  1190.  
  1191.  
  1192. #ifdef HAVE_UNAME
  1193. static char posix_uname__doc__[] =
  1194. "uname() -> (sysname, nodename, release, version, machine)\n\
  1195. Return a tuple identifying the current operating system.";
  1196.  
  1197. static PyObject *
  1198. posix_uname(self, args)
  1199.     PyObject *self;
  1200.     PyObject *args;
  1201. {
  1202.     struct utsname u;
  1203.     int res;
  1204.     if (!PyArg_ParseTuple(args, ":uname"))
  1205.         return NULL;
  1206.     Py_BEGIN_ALLOW_THREADS
  1207.     res = uname(&u);
  1208.     Py_END_ALLOW_THREADS
  1209.     if (res < 0)
  1210.         return posix_error();
  1211.     return Py_BuildValue("(sssss)",
  1212.                  u.sysname,
  1213.                  u.nodename,
  1214.                  u.release,
  1215.                  u.version,
  1216.                  u.machine);
  1217. }
  1218. #endif /* HAVE_UNAME */
  1219.  
  1220.  
  1221. static char posix_utime__doc__[] =
  1222. "utime(path, (atime, utime)) -> None\n\
  1223. utime(path, None) -> None\n\
  1224. Set the access and modified time of the file to the given values.  If the\n\
  1225. second form is used, set the access and modified times to the current time.";
  1226.  
  1227. static PyObject *
  1228. posix_utime(self, args)
  1229.     PyObject *self;
  1230.     PyObject *args;
  1231. {
  1232.     char *path;
  1233.     long atime, mtime;
  1234.     int res;
  1235.     PyObject* arg;
  1236.  
  1237. /* XXX should define struct utimbuf instead, above */
  1238. #ifdef HAVE_UTIME_H
  1239.     struct utimbuf buf;
  1240. #define ATIME buf.actime
  1241. #define MTIME buf.modtime
  1242. #define UTIME_ARG &buf
  1243. #else /* HAVE_UTIME_H */
  1244.     time_t buf[2];
  1245. #define ATIME buf[0]
  1246. #define MTIME buf[1]
  1247. #define UTIME_ARG buf
  1248. #endif /* HAVE_UTIME_H */
  1249.  
  1250.     if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
  1251.         return NULL;
  1252.     if (arg == Py_None) {
  1253.         /* optional time values not given */
  1254.         Py_BEGIN_ALLOW_THREADS
  1255.         res = utime(path, NULL);
  1256.         Py_END_ALLOW_THREADS
  1257.     }
  1258.     else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
  1259.         PyErr_SetString(PyExc_TypeError,
  1260.                   "Second argument must be a 2-tuple of numbers.");
  1261.         return NULL;
  1262.     }
  1263.     else {
  1264.         ATIME = atime;
  1265.         MTIME = mtime;
  1266.         Py_BEGIN_ALLOW_THREADS
  1267.         res = utime(path, UTIME_ARG);
  1268.         Py_END_ALLOW_THREADS
  1269.     }
  1270.     if (res < 0)
  1271.         return posix_error_with_filename(path);
  1272.     Py_INCREF(Py_None);
  1273.     return Py_None;
  1274. #undef UTIME_ARG
  1275. #undef ATIME
  1276. #undef MTIME
  1277. }
  1278.  
  1279.  
  1280. /* Process operations */
  1281.  
  1282. static char posix__exit__doc__[] =
  1283. "_exit(status)\n\
  1284. Exit to the system with specified status, without normal exit processing.";
  1285.  
  1286. static PyObject *
  1287. posix__exit(self, args)
  1288.     PyObject *self;
  1289.     PyObject *args;
  1290. {
  1291.     int sts;
  1292.     if (!PyArg_ParseTuple(args, "i:_exit", &sts))
  1293.         return NULL;
  1294.     _exit(sts);
  1295.     return NULL; /* Make gcc -Wall happy */
  1296. }
  1297.  
  1298.  
  1299. #ifdef HAVE_EXECV
  1300. static char posix_execv__doc__[] =
  1301. "execv(path, args)\n\
  1302. Execute an executable path with arguments, replacing current process.\n\
  1303. \n\
  1304.     path: path of executable file\n\
  1305.     args: tuple or list of strings";
  1306.  
  1307. static PyObject *
  1308. posix_execv(self, args)
  1309.     PyObject *self;
  1310.     PyObject *args;
  1311. {
  1312.     char *path;
  1313.     PyObject *argv;
  1314.     char **argvlist;
  1315.     int i, argc;
  1316.     PyObject *(*getitem) Py_PROTO((PyObject *, int));
  1317.  
  1318.     /* execv has two arguments: (path, argv), where
  1319.        argv is a list or tuple of strings. */
  1320.  
  1321.     if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
  1322.         return NULL;
  1323.     if (PyList_Check(argv)) {
  1324.         argc = PyList_Size(argv);
  1325.         getitem = PyList_GetItem;
  1326.     }
  1327.     else if (PyTuple_Check(argv)) {
  1328.         argc = PyTuple_Size(argv);
  1329.         getitem = PyTuple_GetItem;
  1330.     }
  1331.     else {
  1332.         PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
  1333.         return NULL;
  1334.     }
  1335.  
  1336.     if (argc == 0) {
  1337.         PyErr_SetString(PyExc_ValueError, "empty argument list");
  1338.         return NULL;
  1339.     }
  1340.  
  1341.     argvlist = PyMem_NEW(char *, argc+1);
  1342.     if (argvlist == NULL)
  1343.         return NULL;
  1344.     for (i = 0; i < argc; i++) {
  1345.         if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
  1346.             PyMem_DEL(argvlist);
  1347.             PyErr_SetString(PyExc_TypeError, 
  1348.                     "all arguments must be strings");
  1349.             return NULL;
  1350.             
  1351.         }
  1352.     }
  1353.     argvlist[argc] = NULL;
  1354.  
  1355. #ifdef BAD_EXEC_PROTOTYPES
  1356.     execv(path, (const char **) argvlist);
  1357. #else /* BAD_EXEC_PROTOTYPES */
  1358.     execv(path, argvlist);
  1359. #endif /* BAD_EXEC_PROTOTYPES */
  1360.  
  1361.     /* If we get here it's definitely an error */
  1362.  
  1363.     PyMem_DEL(argvlist);
  1364.     return posix_error();
  1365. }
  1366.  
  1367.  
  1368. static char posix_execve__doc__[] =
  1369. "execve(path, args, env)\n\
  1370. Execute a path with arguments and environment, replacing current process.\n\
  1371. \n\
  1372.     path: path of executable file\n\
  1373.     args: tuple or list of arguments\n\
  1374.     env: dictonary of strings mapping to strings";
  1375.  
  1376. static PyObject *
  1377. posix_execve(self, args)
  1378.     PyObject *self;
  1379.     PyObject *args;
  1380. {
  1381.     char *path;
  1382.     PyObject *argv, *env;
  1383.     char **argvlist;
  1384.     char **envlist;
  1385.     PyObject *key, *val, *keys=NULL, *vals=NULL;
  1386.     int i, pos, argc, envc;
  1387.     PyObject *(*getitem) Py_PROTO((PyObject *, int));
  1388.  
  1389.     /* execve has three arguments: (path, argv, env), where
  1390.        argv is a list or tuple of strings and env is a dictionary
  1391.        like posix.environ. */
  1392.  
  1393.     if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
  1394.         return NULL;
  1395.     if (PyList_Check(argv)) {
  1396.         argc = PyList_Size(argv);
  1397.         getitem = PyList_GetItem;
  1398.     }
  1399.     else if (PyTuple_Check(argv)) {
  1400.         argc = PyTuple_Size(argv);
  1401.         getitem = PyTuple_GetItem;
  1402.     }
  1403.     else {
  1404.         PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
  1405.         return NULL;
  1406.     }
  1407.     if (!PyMapping_Check(env)) {
  1408.         PyErr_SetString(PyExc_TypeError, "env must be mapping object");
  1409.         return NULL;
  1410.     }
  1411.  
  1412.     if (argc == 0) {
  1413.         PyErr_SetString(PyExc_ValueError, 
  1414.                 "empty argument list");
  1415.         return NULL;
  1416.     }
  1417.  
  1418.     argvlist = PyMem_NEW(char *, argc+1);
  1419.     if (argvlist == NULL) {
  1420.         PyErr_NoMemory();
  1421.         return NULL;
  1422.     }
  1423.     for (i = 0; i < argc; i++) {
  1424.         if (!PyArg_Parse((*getitem)(argv, i),
  1425.                  "s;argv must be list of strings",
  1426.                  &argvlist[i]))
  1427.         {
  1428.             goto fail_1;
  1429.         }
  1430.     }
  1431.     argvlist[argc] = NULL;
  1432.  
  1433.     i = PyMapping_Length(env);
  1434.     envlist = PyMem_NEW(char *, i + 1);
  1435.     if (envlist == NULL) {
  1436.         PyErr_NoMemory();
  1437.         goto fail_1;
  1438.     }
  1439.     envc = 0;
  1440.     keys = PyMapping_Keys(env);
  1441.     vals = PyMapping_Values(env);
  1442.     if (!keys || !vals)
  1443.         goto fail_2;
  1444.     
  1445.     for (pos = 0; pos < i; pos++) {
  1446.         char *p, *k, *v;
  1447.  
  1448.         key = PyList_GetItem(keys, pos);
  1449.         val = PyList_GetItem(vals, pos);
  1450.         if (!key || !val)
  1451.             goto fail_2;
  1452.         
  1453.         if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
  1454.             !PyArg_Parse(val, "s;non-string value in env", &v))
  1455.         {
  1456.             goto fail_2;
  1457.         }
  1458.  
  1459. #if defined(PYOS_OS2)
  1460.         /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
  1461.         if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
  1462. #endif
  1463.         p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
  1464.         if (p == NULL) {
  1465.             PyErr_NoMemory();
  1466.             goto fail_2;
  1467.         }
  1468.         sprintf(p, "%s=%s", k, v);
  1469.         envlist[envc++] = p;
  1470. #if defined(PYOS_OS2)
  1471.     }
  1472. #endif
  1473.     }
  1474.     envlist[envc] = 0;
  1475.  
  1476.  
  1477. #ifdef BAD_EXEC_PROTOTYPES
  1478.     execve(path, (const char **)argvlist, envlist);
  1479. #else /* BAD_EXEC_PROTOTYPES */
  1480.     execve(path, argvlist, envlist);
  1481. #endif /* BAD_EXEC_PROTOTYPES */
  1482.     
  1483.     /* If we get here it's definitely an error */
  1484.  
  1485.     (void) posix_error();
  1486.  
  1487.  fail_2:
  1488.     while (--envc >= 0)
  1489.         PyMem_DEL(envlist[envc]);
  1490.     PyMem_DEL(envlist);
  1491.  fail_1:
  1492.     PyMem_DEL(argvlist);
  1493.     Py_XDECREF(vals);
  1494.     Py_XDECREF(keys);
  1495.     return NULL;
  1496. }
  1497. #endif /* HAVE_EXECV */
  1498.  
  1499.  
  1500. #ifdef HAVE_SPAWNV
  1501. static char posix_spawnv__doc__[] =
  1502. "spawnv(mode, path, args)\n\
  1503. Execute an executable path with arguments, replacing current process.\n\
  1504. \n\
  1505.     mode: mode of process creation\n\
  1506.     path: path of executable file\n\
  1507.     args: tuple or list of strings";
  1508.  
  1509. static PyObject *
  1510. posix_spawnv(self, args)
  1511.     PyObject *self;
  1512.     PyObject *args;
  1513. {
  1514.     char *path;
  1515.     PyObject *argv;
  1516.     char **argvlist;
  1517.     int mode, i, argc;
  1518.     PyObject *(*getitem) Py_PROTO((PyObject *, int));
  1519.  
  1520.     /* spawnv has three arguments: (mode, path, argv), where
  1521.        argv is a list or tuple of strings. */
  1522.  
  1523.     if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
  1524.         return NULL;
  1525.     if (PyList_Check(argv)) {
  1526.         argc = PyList_Size(argv);
  1527.         getitem = PyList_GetItem;
  1528.     }
  1529.     else if (PyTuple_Check(argv)) {
  1530.         argc = PyTuple_Size(argv);
  1531.         getitem = PyTuple_GetItem;
  1532.     }
  1533.     else {
  1534.  badarg:
  1535.         PyErr_BadArgument();
  1536.         return NULL;
  1537.     }
  1538.  
  1539.     argvlist = PyMem_NEW(char *, argc+1);
  1540.     if (argvlist == NULL)
  1541.         return NULL;
  1542.     for (i = 0; i < argc; i++) {
  1543.         if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
  1544.             PyMem_DEL(argvlist);
  1545.             goto badarg;
  1546.         }
  1547.     }
  1548.     argvlist[argc] = NULL;
  1549.  
  1550.     if (mode == _OLD_P_OVERLAY)
  1551.         mode = _P_OVERLAY;
  1552.     i = _spawnv(mode, path, argvlist);
  1553.  
  1554.     PyMem_DEL(argvlist);
  1555.  
  1556.     if (i == -1)
  1557.         return posix_error();
  1558.     else
  1559.         return Py_BuildValue("i", i);
  1560. }
  1561.  
  1562.  
  1563. static char posix_spawnve__doc__[] =
  1564. "spawnve(mode, path, args, env)\n\
  1565. Execute a path with arguments and environment, replacing current process.\n\
  1566. \n\
  1567.     mode: mode of process creation\n\
  1568.     path: path of executable file\n\
  1569.     args: tuple or list of arguments\n\
  1570.     env: dictonary of strings mapping to strings";
  1571.  
  1572. static PyObject *
  1573. posix_spawnve(self, args)
  1574.     PyObject *self;
  1575.     PyObject *args;
  1576. {
  1577.     char *path;
  1578.     PyObject *argv, *env;
  1579.     char **argvlist;
  1580.     char **envlist;
  1581.     PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
  1582.     int mode, i, pos, argc, envc;
  1583.     PyObject *(*getitem) Py_PROTO((PyObject *, int));
  1584.  
  1585.     /* spawnve has four arguments: (mode, path, argv, env), where
  1586.        argv is a list or tuple of strings and env is a dictionary
  1587.        like posix.environ. */
  1588.  
  1589.     if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
  1590.         return NULL;
  1591.     if (PyList_Check(argv)) {
  1592.         argc = PyList_Size(argv);
  1593.         getitem = PyList_GetItem;
  1594.     }
  1595.     else if (PyTuple_Check(argv)) {
  1596.         argc = PyTuple_Size(argv);
  1597.         getitem = PyTuple_GetItem;
  1598.     }
  1599.     else {
  1600.         PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
  1601.         return NULL;
  1602.     }
  1603.     if (!PyMapping_Check(env)) {
  1604.         PyErr_SetString(PyExc_TypeError, "env must be mapping object");
  1605.         return NULL;
  1606.     }
  1607.  
  1608.     argvlist = PyMem_NEW(char *, argc+1);
  1609.     if (argvlist == NULL) {
  1610.         PyErr_NoMemory();
  1611.         return NULL;
  1612.     }
  1613.     for (i = 0; i < argc; i++) {
  1614.         if (!PyArg_Parse((*getitem)(argv, i),
  1615.                  "s;argv must be list of strings",
  1616.                  &argvlist[i]))
  1617.         {
  1618.             goto fail_1;
  1619.         }
  1620.     }
  1621.     argvlist[argc] = NULL;
  1622.  
  1623.     i = PyMapping_Length(env);
  1624.     envlist = PyMem_NEW(char *, i + 1);
  1625.     if (envlist == NULL) {
  1626.         PyErr_NoMemory();
  1627.         goto fail_1;
  1628.     }
  1629.     envc = 0;
  1630.     keys = PyMapping_Keys(env);
  1631.     vals = PyMapping_Values(env);
  1632.     if (!keys || !vals)
  1633.         goto fail_2;
  1634.     
  1635.     for (pos = 0; pos < i; pos++) {
  1636.         char *p, *k, *v;
  1637.  
  1638.         key = PyList_GetItem(keys, pos);
  1639.         val = PyList_GetItem(vals, pos);
  1640.         if (!key || !val)
  1641.             goto fail_2;
  1642.         
  1643.         if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
  1644.             !PyArg_Parse(val, "s;non-string value in env", &v))
  1645.         {
  1646.             goto fail_2;
  1647.         }
  1648.         p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
  1649.         if (p == NULL) {
  1650.             PyErr_NoMemory();
  1651.             goto fail_2;
  1652.         }
  1653.         sprintf(p, "%s=%s", k, v);
  1654.         envlist[envc++] = p;
  1655.     }
  1656.     envlist[envc] = 0;
  1657.  
  1658.     if (mode == _OLD_P_OVERLAY)
  1659.         mode = _P_OVERLAY;
  1660.     i = _spawnve(mode, path, argvlist, envlist);
  1661.     if (i == -1)
  1662.         (void) posix_error();
  1663.     else
  1664.         res = Py_BuildValue("i", i);
  1665.  
  1666.  fail_2:
  1667.     while (--envc >= 0)
  1668.         PyMem_DEL(envlist[envc]);
  1669.     PyMem_DEL(envlist);
  1670.  fail_1:
  1671.     PyMem_DEL(argvlist);
  1672.     Py_XDECREF(vals);
  1673.     Py_XDECREF(keys);
  1674.     return res;
  1675. }
  1676. #endif /* HAVE_SPAWNV */
  1677.  
  1678.  
  1679. #ifdef HAVE_FORK
  1680. static char posix_fork__doc__[] =
  1681. "fork() -> pid\n\
  1682. Fork a child process.\n\
  1683. \n\
  1684. Return 0 to child process and PID of child to parent process.";
  1685.  
  1686. static PyObject *
  1687. posix_fork(self, args)
  1688.     PyObject *self;
  1689.     PyObject *args;
  1690. {
  1691.     int pid;
  1692.     if (!PyArg_ParseTuple(args, ":fork"))
  1693.         return NULL;
  1694.     pid = fork();
  1695.     if (pid == -1)
  1696.         return posix_error();
  1697.     PyOS_AfterFork();
  1698.     return PyInt_FromLong((long)pid);
  1699. }
  1700. #endif
  1701.  
  1702.  
  1703. #ifdef HAVE_GETEGID
  1704. static char posix_getegid__doc__[] =
  1705. "getegid() -> egid\n\
  1706. Return the current process's effective group id.";
  1707.  
  1708. static PyObject *
  1709. posix_getegid(self, args)
  1710.     PyObject *self;
  1711.     PyObject *args;
  1712. {
  1713.     if (!PyArg_ParseTuple(args, ":getegid"))
  1714.         return NULL;
  1715.     return PyInt_FromLong((long)getegid());
  1716. }
  1717. #endif
  1718.  
  1719.  
  1720. #ifdef HAVE_GETEUID
  1721. static char posix_geteuid__doc__[] =
  1722. "geteuid() -> euid\n\
  1723. Return the current process's effective user id.";
  1724.  
  1725. static PyObject *
  1726. posix_geteuid(self, args)
  1727.     PyObject *self;
  1728.     PyObject *args;
  1729. {
  1730.     if (!PyArg_ParseTuple(args, ":geteuid"))
  1731.         return NULL;
  1732.     return PyInt_FromLong((long)geteuid());
  1733. }
  1734. #endif
  1735.  
  1736.  
  1737. #ifdef HAVE_GETGID
  1738. static char posix_getgid__doc__[] =
  1739. "getgid() -> gid\n\
  1740. Return the current process's group id.";
  1741.  
  1742. static PyObject *
  1743. posix_getgid(self, args)
  1744.     PyObject *self;
  1745.     PyObject *args;
  1746. {
  1747.     if (!PyArg_ParseTuple(args, ":getgid"))
  1748.         return NULL;
  1749.     return PyInt_FromLong((long)getgid());
  1750. }
  1751. #endif
  1752.  
  1753.  
  1754. static char posix_getpid__doc__[] =
  1755. "getpid() -> pid\n\
  1756. Return the current process id";
  1757.  
  1758. static PyObject *
  1759. posix_getpid(self, args)
  1760.     PyObject *self;
  1761.     PyObject *args;
  1762. {
  1763.     if (!PyArg_ParseTuple(args, ":getpid"))
  1764.         return NULL;
  1765.     return PyInt_FromLong((long)getpid());
  1766. }
  1767.  
  1768.  
  1769. #ifdef HAVE_GETGROUPS
  1770. static char posix_getgroups__doc__[] = "\
  1771. getgroups() -> list of group IDs\n\
  1772. Return list of supplemental group IDs for the process.";
  1773.  
  1774. static PyObject *
  1775. posix_getgroups(self, args)
  1776.      PyObject *self;
  1777.      PyObject *args;
  1778. {
  1779.     PyObject *result = NULL;
  1780.  
  1781.     if (PyArg_ParseTuple(args, ":getgroups")) {
  1782. #ifdef NGROUPS_MAX
  1783. #define MAX_GROUPS NGROUPS_MAX
  1784. #else
  1785.         /* defined to be 16 on Solaris7, so this should be a small number */
  1786. #define MAX_GROUPS 64
  1787. #endif
  1788.         gid_t grouplist[MAX_GROUPS];
  1789.         int n;
  1790.  
  1791.         n = getgroups(MAX_GROUPS, grouplist);
  1792.         if (n < 0)
  1793.             posix_error();
  1794.         else {
  1795.             result = PyList_New(n);
  1796.             if (result != NULL) {
  1797.                 PyObject *o;
  1798.                 int i;
  1799.                 for (i = 0; i < n; ++i) {
  1800.                     o = PyInt_FromLong((long)grouplist[i]);
  1801.                     if (o == NULL) {
  1802.                         Py_DECREF(result);
  1803.                         result = NULL;
  1804.                         break;
  1805.                     }
  1806.                     PyList_SET_ITEM(result, i, o);
  1807.                 }
  1808.             }
  1809.         }
  1810.     }
  1811.     return result;
  1812. }
  1813. #endif
  1814.  
  1815. #ifdef HAVE_GETPGRP
  1816. static char posix_getpgrp__doc__[] =
  1817. "getpgrp() -> pgrp\n\
  1818. Return the current process group id.";
  1819.  
  1820. static PyObject *
  1821. posix_getpgrp(self, args)
  1822.     PyObject *self;
  1823.     PyObject *args;
  1824. {
  1825.     if (!PyArg_ParseTuple(args, ":getpgrp"))
  1826.         return NULL;
  1827. #ifdef GETPGRP_HAVE_ARG
  1828.     return PyInt_FromLong((long)getpgrp(0));
  1829. #else /* GETPGRP_HAVE_ARG */
  1830.     return PyInt_FromLong((long)getpgrp());
  1831. #endif /* GETPGRP_HAVE_ARG */
  1832. }
  1833. #endif /* HAVE_GETPGRP */
  1834.  
  1835.  
  1836. #ifdef HAVE_SETPGRP
  1837. static char posix_setpgrp__doc__[] =
  1838. "setpgrp() -> None\n\
  1839. Make this process a session leader.";
  1840.  
  1841. static PyObject *
  1842. posix_setpgrp(self, args)
  1843.     PyObject *self;
  1844.     PyObject *args;
  1845. {
  1846.     if (!PyArg_ParseTuple(args, ":setpgrp"))
  1847.         return NULL;
  1848. #ifdef SETPGRP_HAVE_ARG
  1849.     if (setpgrp(0, 0) < 0)
  1850. #else /* SETPGRP_HAVE_ARG */
  1851.     if (setpgrp() < 0)
  1852. #endif /* SETPGRP_HAVE_ARG */
  1853.         return posix_error();
  1854.     Py_INCREF(Py_None);
  1855.     return Py_None;
  1856. }
  1857.  
  1858. #endif /* HAVE_SETPGRP */
  1859.  
  1860. #ifdef HAVE_GETPPID
  1861. static char posix_getppid__doc__[] =
  1862. "getppid() -> ppid\n\
  1863. Return the parent's process id.";
  1864.  
  1865. static PyObject *
  1866. posix_getppid(self, args)
  1867.     PyObject *self;
  1868.     PyObject *args;
  1869. {
  1870.     if (!PyArg_ParseTuple(args, ":getppid"))
  1871.         return NULL;
  1872.     return PyInt_FromLong((long)getppid());
  1873. }
  1874. #endif
  1875.  
  1876.  
  1877. #ifdef HAVE_GETLOGIN
  1878. static char posix_getlogin__doc__[] = "\
  1879. getlogin() -> string\n\
  1880. Return the actual login name.";
  1881.  
  1882. static PyObject *
  1883. posix_getlogin(self, args)
  1884.     PyObject *self;
  1885.     PyObject *args;
  1886. {
  1887.     PyObject *result = NULL;
  1888.  
  1889.     if (PyArg_ParseTuple(args, ":getlogin")) {
  1890.         char *name = getlogin();
  1891.  
  1892.         if (name == NULL)
  1893.             posix_error();
  1894.         else
  1895.             result = PyString_FromString(name);
  1896.     }
  1897.     return result;
  1898. }
  1899. #endif
  1900.  
  1901. #ifdef HAVE_GETUID
  1902. static char posix_getuid__doc__[] =
  1903. "getuid() -> uid\n\
  1904. Return the current process's user id.";
  1905.  
  1906. static PyObject *
  1907. posix_getuid(self, args)
  1908.     PyObject *self;
  1909.     PyObject *args;
  1910. {
  1911.     if (!PyArg_ParseTuple(args, ":getuid"))
  1912.         return NULL;
  1913.     return PyInt_FromLong((long)getuid());
  1914. }
  1915. #endif
  1916.  
  1917.  
  1918. #ifdef HAVE_KILL
  1919. static char posix_kill__doc__[] =
  1920. "kill(pid, sig) -> None\n\
  1921. Kill a process with a signal.";
  1922.  
  1923. static PyObject *
  1924. posix_kill(self, args)
  1925.     PyObject *self;
  1926.     PyObject *args;
  1927. {
  1928.     int pid, sig;
  1929.     if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
  1930.         return NULL;
  1931. #if defined(PYOS_OS2)
  1932.     if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
  1933.         APIRET rc;
  1934.         if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
  1935.             return os2_error(rc);
  1936.  
  1937.     } else if (sig == XCPT_SIGNAL_KILLPROC) {
  1938.         APIRET rc;
  1939.         if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
  1940.             return os2_error(rc);
  1941.  
  1942.     } else
  1943.         return NULL; /* Unrecognized Signal Requested */
  1944. #else
  1945.     if (kill(pid, sig) == -1)
  1946.         return posix_error();
  1947. #endif
  1948.     Py_INCREF(Py_None);
  1949.     return Py_None;
  1950. }
  1951. #endif
  1952.  
  1953. #ifdef HAVE_PLOCK
  1954.  
  1955. #ifdef HAVE_SYS_LOCK_H
  1956. #include <sys/lock.h>
  1957. #endif
  1958.  
  1959. static char posix_plock__doc__[] =
  1960. "plock(op) -> None\n\
  1961. Lock program segments into memory.";
  1962.  
  1963. static PyObject *
  1964. posix_plock(self, args)
  1965.     PyObject *self;
  1966.     PyObject *args;
  1967. {
  1968.     int op;
  1969.     if (!PyArg_ParseTuple(args, "i:plock", &op))
  1970.         return NULL;
  1971.     if (plock(op) == -1)
  1972.         return posix_error();
  1973.     Py_INCREF(Py_None);
  1974.     return Py_None;
  1975. }
  1976. #endif
  1977.  
  1978.  
  1979. #ifdef HAVE_POPEN
  1980. static char posix_popen__doc__[] =
  1981. "popen(command [, mode='r' [, bufsize]]) -> pipe\n\
  1982. Open a pipe to/from a command returning a file object.";
  1983.  
  1984. #if defined(PYOS_OS2)
  1985. static int
  1986. async_system(const char *command)
  1987. {
  1988.     char        *p, errormsg[256], args[1024];
  1989.     RESULTCODES  rcodes;
  1990.     APIRET       rc;
  1991.     char        *shell = getenv("COMSPEC");
  1992.     if (!shell)
  1993.         shell = "cmd";
  1994.  
  1995.     strcpy(args, shell);
  1996.     p = &args[ strlen(args)+1 ];
  1997.     strcpy(p, "/c ");
  1998.     strcat(p, command);
  1999.     p += strlen(p) + 1;
  2000.     *p = '\0';
  2001.  
  2002.     rc = DosExecPgm(errormsg, sizeof(errormsg),
  2003.                     EXEC_ASYNC, /* Execute Async w/o Wait for Results */
  2004.                     args,
  2005.                     NULL,       /* Inherit Parent's Environment */
  2006.                     &rcodes, shell);
  2007.     return rc;
  2008. }
  2009.  
  2010. static FILE *
  2011. popen(const char *command, const char *mode, int pipesize, int *err)
  2012. {
  2013.     HFILE    rhan, whan;
  2014.     FILE    *retfd = NULL;
  2015.     APIRET   rc = DosCreatePipe(&rhan, &whan, pipesize);
  2016.  
  2017.     if (rc != NO_ERROR) {
  2018.     *err = rc;
  2019.         return NULL; /* ERROR - Unable to Create Anon Pipe */
  2020.     }
  2021.  
  2022.     if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
  2023.         int oldfd = dup(1);      /* Save STDOUT Handle in Another Handle */
  2024.  
  2025.         DosEnterCritSec();      /* Stop Other Threads While Changing Handles */
  2026.         close(1);                /* Make STDOUT Available for Reallocation */
  2027.  
  2028.         if (dup2(whan, 1) == 0) {      /* Connect STDOUT to Pipe Write Side */
  2029.             DosClose(whan);            /* Close Now-Unused Pipe Write Handle */
  2030.  
  2031.             if (async_system(command) == NO_ERROR)
  2032.                 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
  2033.         }
  2034.  
  2035.         dup2(oldfd, 1);          /* Reconnect STDOUT to Original Handle */
  2036.         DosExitCritSec();        /* Now Allow Other Threads to Run */
  2037.  
  2038.         close(oldfd);            /* And Close Saved STDOUT Handle */
  2039.         return retfd;            /* Return fd of Pipe or NULL if Error */
  2040.  
  2041.     } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
  2042.         int oldfd = dup(0);      /* Save STDIN Handle in Another Handle */
  2043.  
  2044.         DosEnterCritSec();      /* Stop Other Threads While Changing Handles */
  2045.         close(0);                /* Make STDIN Available for Reallocation */
  2046.  
  2047.         if (dup2(rhan, 0) == 0)     { /* Connect STDIN to Pipe Read Side */
  2048.             DosClose(rhan);           /* Close Now-Unused Pipe Read Handle */
  2049.  
  2050.             if (async_system(command) == NO_ERROR)
  2051.                 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
  2052.         }
  2053.  
  2054.         dup2(oldfd, 0);          /* Reconnect STDIN to Original Handle */
  2055.         DosExitCritSec();        /* Now Allow Other Threads to Run */
  2056.  
  2057.         close(oldfd);            /* And Close Saved STDIN Handle */
  2058.         return retfd;            /* Return fd of Pipe or NULL if Error */
  2059.  
  2060.     } else {
  2061.     *err = ERROR_INVALID_ACCESS;
  2062.         return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
  2063.     }
  2064. }
  2065.  
  2066. static PyObject *
  2067. posix_popen(self, args)
  2068.     PyObject *self;
  2069.     PyObject *args;
  2070. {
  2071.     char *name;
  2072.     char *mode = "r";
  2073.     int   err, bufsize = -1;
  2074.     FILE *fp;
  2075.     PyObject *f;
  2076.     if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
  2077.         return NULL;
  2078.     Py_BEGIN_ALLOW_THREADS
  2079.     fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
  2080.     Py_END_ALLOW_THREADS
  2081.     if (fp == NULL)
  2082.         return os2_error(err);
  2083.  
  2084.     f = PyFile_FromFile(fp, name, mode, fclose);
  2085.     if (f != NULL)
  2086.         PyFile_SetBufSize(f, bufsize);
  2087.     return f;
  2088. }
  2089.  
  2090. #else
  2091. static PyObject *
  2092. posix_popen(self, args)
  2093.     PyObject *self;
  2094.     PyObject *args;
  2095. {
  2096.     char *name;
  2097.     char *mode = "r";
  2098.     int bufsize = -1;
  2099.     FILE *fp;
  2100.     PyObject *f;
  2101.     if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
  2102.         return NULL;
  2103.     Py_BEGIN_ALLOW_THREADS
  2104.     fp = popen(name, mode);
  2105.     Py_END_ALLOW_THREADS
  2106.     if (fp == NULL)
  2107.         return posix_error();
  2108.     f = PyFile_FromFile(fp, name, mode, pclose);
  2109.     if (f != NULL)
  2110.         PyFile_SetBufSize(f, bufsize);
  2111.     return f;
  2112. }
  2113. #endif
  2114.  
  2115. #endif /* HAVE_POPEN */
  2116.  
  2117.  
  2118. #ifdef HAVE_SETUID
  2119. static char posix_setuid__doc__[] =
  2120. "setuid(uid) -> None\n\
  2121. Set the current process's user id.";
  2122. static PyObject *
  2123. posix_setuid(self, args)
  2124.     PyObject *self;
  2125.     PyObject *args;
  2126. {
  2127.     int uid;
  2128.     if (!PyArg_ParseTuple(args, "i:setuid", &uid))
  2129.         return NULL;
  2130.     if (setuid(uid) < 0)
  2131.         return posix_error();
  2132.     Py_INCREF(Py_None);
  2133.     return Py_None;
  2134. }
  2135. #endif /* HAVE_SETUID */
  2136.  
  2137.  
  2138. #ifdef HAVE_SETGID
  2139. static char posix_setgid__doc__[] =
  2140. "setgid(gid) -> None\n\
  2141. Set the current process's group id.";
  2142.  
  2143. static PyObject *
  2144. posix_setgid(self, args)
  2145.     PyObject *self;
  2146.     PyObject *args;
  2147. {
  2148.     int gid;
  2149.     if (!PyArg_ParseTuple(args, "i:setgid", &gid))
  2150.         return NULL;
  2151.     if (setgid(gid) < 0)
  2152.         return posix_error();
  2153.     Py_INCREF(Py_None);
  2154.     return Py_None;
  2155. }
  2156. #endif /* HAVE_SETGID */
  2157.  
  2158.  
  2159. #ifdef HAVE_WAITPID
  2160. static char posix_waitpid__doc__[] =
  2161. "waitpid(pid, options) -> (pid, status)\n\
  2162. Wait for completion of a give child process.";
  2163.  
  2164. static PyObject *
  2165. posix_waitpid(self, args)
  2166.     PyObject *self;
  2167.     PyObject *args;
  2168. {
  2169.     int pid, options;
  2170. #ifdef UNION_WAIT
  2171.     union wait status;
  2172. #define status_i (status.w_status)
  2173. #else
  2174.     int status;
  2175. #define status_i status
  2176. #endif
  2177.     status_i = 0;
  2178.  
  2179.     if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
  2180.         return NULL;
  2181.     Py_BEGIN_ALLOW_THREADS
  2182. #ifdef NeXT
  2183.     pid = wait4(pid, &status, options, NULL);
  2184. #else
  2185.     pid = waitpid(pid, &status, options);
  2186. #endif
  2187.     Py_END_ALLOW_THREADS
  2188.     if (pid == -1)
  2189.         return posix_error();
  2190.     else
  2191.         return Py_BuildValue("ii", pid, status_i);
  2192. }
  2193. #endif /* HAVE_WAITPID */
  2194.  
  2195.  
  2196. #ifdef HAVE_WAIT
  2197. static char posix_wait__doc__[] =
  2198. "wait() -> (pid, status)\n\
  2199. Wait for completion of a child process.";
  2200.  
  2201. static PyObject *
  2202. posix_wait(self, args)
  2203.     PyObject *self;
  2204.     PyObject *args;
  2205. {
  2206.     int pid;
  2207. #ifdef UNION_WAIT
  2208.     union wait status;
  2209. #define status_i (status.w_status)
  2210. #else
  2211.     int status;
  2212. #define status_i status
  2213. #endif
  2214.         if (!PyArg_ParseTuple(args, ":wait"))
  2215.                 return NULL;
  2216.     status_i = 0;
  2217.     Py_BEGIN_ALLOW_THREADS
  2218.     pid = wait(&status);
  2219.     Py_END_ALLOW_THREADS
  2220.     if (pid == -1)
  2221.         return posix_error();
  2222.     else
  2223.         return Py_BuildValue("ii", pid, status_i);
  2224. #undef status_i
  2225. }
  2226. #endif
  2227.  
  2228.  
  2229. static char posix_lstat__doc__[] =
  2230. "lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
  2231. Like stat(path), but do not follow symbolic links.";
  2232.  
  2233. static PyObject *
  2234. posix_lstat(self, args)
  2235.     PyObject *self;
  2236.     PyObject *args;
  2237. {
  2238. #ifdef HAVE_LSTAT
  2239.     return posix_do_stat(self, args, "s:lstat", lstat);
  2240. #else /* !HAVE_LSTAT */
  2241.     return posix_do_stat(self, args, "s:lstat", stat);
  2242. #endif /* !HAVE_LSTAT */
  2243. }
  2244.  
  2245.  
  2246. #ifdef HAVE_READLINK
  2247. static char posix_readlink__doc__[] =
  2248. "readlink(path) -> path\n\
  2249. Return a string representing the path to which the symbolic link points.";
  2250.  
  2251. static PyObject *
  2252. posix_readlink(self, args)
  2253.     PyObject *self;
  2254.     PyObject *args;
  2255. {
  2256.     char buf[MAXPATHLEN];
  2257.     char *path;
  2258.     int n;
  2259.     if (!PyArg_ParseTuple(args, "s:readlink", &path))
  2260.         return NULL;
  2261.     Py_BEGIN_ALLOW_THREADS
  2262.     n = readlink(path, buf, (int) sizeof buf);
  2263.     Py_END_ALLOW_THREADS
  2264.     if (n < 0)
  2265.         return posix_error_with_filename(path);
  2266.     return PyString_FromStringAndSize(buf, n);
  2267. }
  2268. #endif /* HAVE_READLINK */
  2269.  
  2270.  
  2271. #ifdef HAVE_SYMLINK
  2272. static char posix_symlink__doc__[] =
  2273. "symlink(src, dst) -> None\n\
  2274. Create a symbolic link.";
  2275.  
  2276. static PyObject *
  2277. posix_symlink(self, args)
  2278.     PyObject *self;
  2279.     PyObject *args;
  2280. {
  2281.     return posix_2str(args, "ss:symlink", symlink);
  2282. }
  2283. #endif /* HAVE_SYMLINK */
  2284.  
  2285.  
  2286. #ifdef HAVE_TIMES
  2287. #ifndef HZ
  2288. #define HZ 60 /* Universal constant :-) */
  2289. #endif /* HZ */
  2290.     
  2291. #if defined(PYCC_VACPP) && defined(PYOS_OS2)
  2292. static long
  2293. system_uptime()
  2294. {
  2295.     ULONG     value = 0;
  2296.  
  2297.     Py_BEGIN_ALLOW_THREADS
  2298.     DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
  2299.     Py_END_ALLOW_THREADS
  2300.  
  2301.     return value;
  2302. }
  2303.  
  2304. static PyObject *
  2305. posix_times(self, args)
  2306.     PyObject *self;
  2307.     PyObject *args;
  2308. {
  2309.     if (!PyArg_ParseTuple(args, ":times"))
  2310.         return NULL;
  2311.  
  2312.     /* Currently Only Uptime is Provided -- Others Later */
  2313.     return Py_BuildValue("ddddd",
  2314.                  (double)0 /* t.tms_utime / HZ */,
  2315.                  (double)0 /* t.tms_stime / HZ */,
  2316.                  (double)0 /* t.tms_cutime / HZ */,
  2317.                  (double)0 /* t.tms_cstime / HZ */,
  2318.                  (double)system_uptime() / 1000);
  2319. }
  2320. #else /* not OS2 */
  2321. static PyObject *
  2322. posix_times(self, args)
  2323.     PyObject *self;
  2324.     PyObject *args;
  2325. {
  2326.     struct tms t;
  2327.     clock_t c;
  2328.     if (!PyArg_ParseTuple(args, ":times"))
  2329.         return NULL;
  2330.     errno = 0;
  2331.     c = times(&t);
  2332.     if (c == (clock_t) -1)
  2333.         return posix_error();
  2334.     return Py_BuildValue("ddddd",
  2335.                  (double)t.tms_utime / HZ,
  2336.                  (double)t.tms_stime / HZ,
  2337.                  (double)t.tms_cutime / HZ,
  2338.                  (double)t.tms_cstime / HZ,
  2339.                  (double)c / HZ);
  2340. }
  2341. #endif /* not OS2 */
  2342. #endif /* HAVE_TIMES */
  2343.  
  2344.  
  2345. #ifdef MS_WIN32
  2346. #define HAVE_TIMES    /* so the method table will pick it up */
  2347. static PyObject *
  2348. posix_times(self, args)
  2349.     PyObject *self;
  2350.     PyObject *args;
  2351. {
  2352.     FILETIME create, exit, kernel, user;
  2353.     HANDLE hProc;
  2354.     if (!PyArg_ParseTuple(args, ":times"))
  2355.         return NULL;
  2356.     hProc = GetCurrentProcess();
  2357.     GetProcessTimes(hProc, &create, &exit, &kernel, &user);
  2358.     /* The fields of a FILETIME structure are the hi and lo part
  2359.        of a 64-bit value expressed in 100 nanosecond units.
  2360.        1e7 is one second in such units; 1e-7 the inverse.
  2361.        429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
  2362.     */
  2363.     return Py_BuildValue(
  2364.         "ddddd",
  2365.         (double)(kernel.dwHighDateTime*429.4967296 +
  2366.                  kernel.dwLowDateTime*1e-7),
  2367.         (double)(user.dwHighDateTime*429.4967296 +
  2368.                  user.dwLowDateTime*1e-7),
  2369.         (double)0,
  2370.         (double)0,
  2371.         (double)0);
  2372. }
  2373. #endif /* MS_WIN32 */
  2374.  
  2375. #ifdef HAVE_TIMES
  2376. static char posix_times__doc__[] =
  2377. "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
  2378. Return a tuple of floating point numbers indicating process times.";
  2379. #endif
  2380.  
  2381.  
  2382. #ifdef HAVE_SETSID
  2383. static char posix_setsid__doc__[] =
  2384. "setsid() -> None\n\
  2385. Call the system call setsid().";
  2386.  
  2387. static PyObject *
  2388. posix_setsid(self, args)
  2389.     PyObject *self;
  2390.     PyObject *args;
  2391. {
  2392.     if (!PyArg_ParseTuple(args, ":setsid"))
  2393.         return NULL;
  2394.     if (setsid() < 0)
  2395.         return posix_error();
  2396.     Py_INCREF(Py_None);
  2397.     return Py_None;
  2398. }
  2399. #endif /* HAVE_SETSID */
  2400.  
  2401. #ifdef HAVE_SETPGID
  2402. static char posix_setpgid__doc__[] =
  2403. "setpgid(pid, pgrp) -> None\n\
  2404. Call the system call setpgid().";
  2405.  
  2406. static PyObject *
  2407. posix_setpgid(self, args)
  2408.     PyObject *self;
  2409.     PyObject *args;
  2410. {
  2411.     int pid, pgrp;
  2412.     if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
  2413.         return NULL;
  2414.     if (setpgid(pid, pgrp) < 0)
  2415.         return posix_error();
  2416.     Py_INCREF(Py_None);
  2417.     return Py_None;
  2418. }
  2419. #endif /* HAVE_SETPGID */
  2420.  
  2421.  
  2422. #ifdef HAVE_TCGETPGRP
  2423. static char posix_tcgetpgrp__doc__[] =
  2424. "tcgetpgrp(fd) -> pgid\n\
  2425. Return the process group associated with the terminal given by a fd.";
  2426.  
  2427. static PyObject *
  2428. posix_tcgetpgrp(self, args)
  2429.     PyObject *self;
  2430.     PyObject *args;
  2431. {
  2432.     int fd, pgid;
  2433.     if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
  2434.         return NULL;
  2435.     pgid = tcgetpgrp(fd);
  2436.     if (pgid < 0)
  2437.         return posix_error();
  2438.     return PyInt_FromLong((long)pgid);
  2439. }
  2440. #endif /* HAVE_TCGETPGRP */
  2441.  
  2442.  
  2443. #ifdef HAVE_TCSETPGRP
  2444. static char posix_tcsetpgrp__doc__[] =
  2445. "tcsetpgrp(fd, pgid) -> None\n\
  2446. Set the process group associated with the terminal given by a fd.";
  2447.  
  2448. static PyObject *
  2449. posix_tcsetpgrp(self, args)
  2450.     PyObject *self;
  2451.     PyObject *args;
  2452. {
  2453.     int fd, pgid;
  2454.     if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
  2455.         return NULL;
  2456.     if (tcsetpgrp(fd, pgid) < 0)
  2457.         return posix_error();
  2458.     Py_INCREF(Py_None);
  2459.     return Py_None;
  2460. }
  2461. #endif /* HAVE_TCSETPGRP */
  2462.  
  2463. /* Functions acting on file descriptors */
  2464.  
  2465. static char posix_open__doc__[] =
  2466. "open(filename, flag [, mode=0777]) -> fd\n\
  2467. Open a file (for low level IO).";
  2468.  
  2469. static PyObject *
  2470. posix_open(self, args)
  2471.     PyObject *self;
  2472.     PyObject *args;
  2473. {
  2474.     char *file;
  2475.     int flag;
  2476.     int mode = 0777;
  2477.     int fd;
  2478.     if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
  2479.         return NULL;
  2480.  
  2481.     Py_BEGIN_ALLOW_THREADS
  2482.     fd = open(file, flag, mode);
  2483.     Py_END_ALLOW_THREADS
  2484.     if (fd < 0)
  2485.         return posix_error_with_filename(file);
  2486.     return PyInt_FromLong((long)fd);
  2487. }
  2488.  
  2489.  
  2490. static char posix_close__doc__[] =
  2491. "close(fd) -> None\n\
  2492. Close a file descriptor (for low level IO).";
  2493.  
  2494. static PyObject *
  2495. posix_close(self, args)
  2496.     PyObject *self;
  2497.     PyObject *args;
  2498. {
  2499.     int fd, res;
  2500.     if (!PyArg_ParseTuple(args, "i:close", &fd))
  2501.         return NULL;
  2502.     Py_BEGIN_ALLOW_THREADS
  2503.     res = close(fd);
  2504.     Py_END_ALLOW_THREADS
  2505.     if (res < 0)
  2506.         return posix_error();
  2507.     Py_INCREF(Py_None);
  2508.     return Py_None;
  2509. }
  2510.  
  2511.  
  2512. static char posix_dup__doc__[] =
  2513. "dup(fd) -> fd2\n\
  2514. Return a duplicate of a file descriptor.";
  2515.  
  2516. static PyObject *
  2517. posix_dup(self, args)
  2518.     PyObject *self;
  2519.     PyObject *args;
  2520. {
  2521.     int fd;
  2522.     if (!PyArg_ParseTuple(args, "i:dup", &fd))
  2523.         return NULL;
  2524.     Py_BEGIN_ALLOW_THREADS
  2525.     fd = dup(fd);
  2526.     Py_END_ALLOW_THREADS
  2527.     if (fd < 0)
  2528.         return posix_error();
  2529.     return PyInt_FromLong((long)fd);
  2530. }
  2531.  
  2532.  
  2533. static char posix_dup2__doc__[] =
  2534. "dup2(fd, fd2) -> None\n\
  2535. Duplicate file descriptor.";
  2536.  
  2537. static PyObject *
  2538. posix_dup2(self, args)
  2539.     PyObject *self;
  2540.     PyObject *args;
  2541. {
  2542.     int fd, fd2, res;
  2543.     if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
  2544.         return NULL;
  2545.     Py_BEGIN_ALLOW_THREADS
  2546.     res = dup2(fd, fd2);
  2547.     Py_END_ALLOW_THREADS
  2548.     if (res < 0)
  2549.         return posix_error();
  2550.     Py_INCREF(Py_None);
  2551.     return Py_None;
  2552. }
  2553.  
  2554.  
  2555. static char posix_lseek__doc__[] =
  2556. "lseek(fd, pos, how) -> newpos\n\
  2557. Set the current position of a file descriptor.";
  2558.  
  2559. static PyObject *
  2560. posix_lseek(self, args)
  2561.     PyObject *self;
  2562.     PyObject *args;
  2563. {
  2564.     int fd, how;
  2565.     off_t pos, res;
  2566.     PyObject *posobj;
  2567.     if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
  2568.         return NULL;
  2569. #ifdef SEEK_SET
  2570.     /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
  2571.     switch (how) {
  2572.     case 0: how = SEEK_SET; break;
  2573.     case 1: how = SEEK_CUR; break;
  2574.     case 2: how = SEEK_END; break;
  2575.     }
  2576. #endif /* SEEK_END */
  2577.  
  2578. #if !defined(HAVE_LARGEFILE_SUPPORT)
  2579.     pos = PyInt_AsLong(posobj);
  2580. #else
  2581.     pos = PyLong_Check(posobj) ?
  2582.         PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
  2583. #endif
  2584.     if (PyErr_Occurred())
  2585.         return NULL;
  2586.  
  2587.     Py_BEGIN_ALLOW_THREADS
  2588.     res = lseek(fd, pos, how);
  2589.     Py_END_ALLOW_THREADS
  2590.     if (res < 0)
  2591.         return posix_error();
  2592.  
  2593. #if !defined(HAVE_LARGEFILE_SUPPORT)
  2594.     return PyInt_FromLong(res);
  2595. #else
  2596.     return PyLong_FromLongLong(res);
  2597. #endif
  2598. }
  2599.  
  2600.  
  2601. static char posix_read__doc__[] =
  2602. "read(fd, buffersize) -> string\n\
  2603. Read a file descriptor.";
  2604.  
  2605. static PyObject *
  2606. posix_read(self, args)
  2607.     PyObject *self;
  2608.     PyObject *args;
  2609. {
  2610.     int fd, size, n;
  2611.     PyObject *buffer;
  2612.     if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
  2613.         return NULL;
  2614.     buffer = PyString_FromStringAndSize((char *)NULL, size);
  2615.     if (buffer == NULL)
  2616.         return NULL;
  2617.     Py_BEGIN_ALLOW_THREADS
  2618.     n = read(fd, PyString_AsString(buffer), size);
  2619.     Py_END_ALLOW_THREADS
  2620.     if (n < 0) {
  2621.         Py_DECREF(buffer);
  2622.         return posix_error();
  2623.     }
  2624.     if (n != size)
  2625.         _PyString_Resize(&buffer, n);
  2626.     return buffer;
  2627. }
  2628.  
  2629.  
  2630. static char posix_write__doc__[] =
  2631. "write(fd, string) -> byteswritten\n\
  2632. Write a string to a file descriptor.";
  2633.  
  2634. static PyObject *
  2635. posix_write(self, args)
  2636.     PyObject *self;
  2637.     PyObject *args;
  2638. {
  2639.     int fd, size;
  2640.     char *buffer;
  2641.     if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
  2642.         return NULL;
  2643.     Py_BEGIN_ALLOW_THREADS
  2644.     size = write(fd, buffer, size);
  2645.     Py_END_ALLOW_THREADS
  2646.     if (size < 0)
  2647.         return posix_error();
  2648.     return PyInt_FromLong((long)size);
  2649. }
  2650.  
  2651.  
  2652. static char posix_fstat__doc__[]=
  2653. "fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
  2654. Like stat(), but for an open file descriptor.";
  2655.  
  2656. static PyObject *
  2657. posix_fstat(self, args)
  2658.     PyObject *self;
  2659.     PyObject *args;
  2660. {
  2661.     int fd;
  2662.     struct stat st;
  2663.     int res;
  2664.     if (!PyArg_ParseTuple(args, "i:fstat", &fd))
  2665.         return NULL;
  2666.     Py_BEGIN_ALLOW_THREADS
  2667.     res = fstat(fd, &st);
  2668.     Py_END_ALLOW_THREADS
  2669.     if (res != 0)
  2670.         return posix_error();
  2671. #if !defined(HAVE_LARGEFILE_SUPPORT)
  2672.     return Py_BuildValue("(llllllllll)",
  2673.                  (long)st.st_mode,
  2674.                  (long)st.st_ino,
  2675.                  (long)st.st_dev,
  2676.                  (long)st.st_nlink,
  2677.                  (long)st.st_uid,
  2678.                  (long)st.st_gid,
  2679.                  (long)st.st_size,
  2680.                  (long)st.st_atime,
  2681.                  (long)st.st_mtime,
  2682.                  (long)st.st_ctime);
  2683. #else
  2684.     return Py_BuildValue("(lLllllLlll)",
  2685.                  (long)st.st_mode,
  2686.                  (LONG_LONG)st.st_ino,
  2687.                  (long)st.st_dev,
  2688.                  (long)st.st_nlink,
  2689.                  (long)st.st_uid,
  2690.                  (long)st.st_gid,
  2691.                  (LONG_LONG)st.st_size,
  2692.                  (long)st.st_atime,
  2693.                  (long)st.st_mtime,
  2694.                  (long)st.st_ctime);
  2695. #endif
  2696. }
  2697.  
  2698.  
  2699. static char posix_fdopen__doc__[] =
  2700. "fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
  2701. Return an open file object connected to a file descriptor.";
  2702.  
  2703. static PyObject *
  2704. posix_fdopen(self, args)
  2705.     PyObject *self;
  2706.     PyObject *args;
  2707. {
  2708.     extern int fclose Py_PROTO((FILE *));
  2709.     int fd;
  2710.     char *mode = "r";
  2711.     int bufsize = -1;
  2712.     FILE *fp;
  2713.     PyObject *f;
  2714.     if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
  2715.         return NULL;
  2716.  
  2717.     Py_BEGIN_ALLOW_THREADS
  2718.     fp = fdopen(fd, mode);
  2719.     Py_END_ALLOW_THREADS
  2720.     if (fp == NULL)
  2721.         return posix_error();
  2722.     f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
  2723.     if (f != NULL)
  2724.         PyFile_SetBufSize(f, bufsize);
  2725.     return f;
  2726. }
  2727.  
  2728.  
  2729. #ifdef HAVE_PIPE
  2730. static char posix_pipe__doc__[] =
  2731. "pipe() -> (read_end, write_end)\n\
  2732. Create a pipe.";
  2733.  
  2734. static PyObject *
  2735. posix_pipe(self, args)
  2736.     PyObject *self;
  2737.     PyObject *args;
  2738. {
  2739. #if defined(PYOS_OS2)
  2740.     HFILE read, write;
  2741.     APIRET rc;
  2742.  
  2743.     if (!PyArg_ParseTuple(args, ":pipe"))
  2744.         return NULL;
  2745.  
  2746.     Py_BEGIN_ALLOW_THREADS
  2747.     rc = DosCreatePipe( &read, &write, 4096);
  2748.     Py_END_ALLOW_THREADS
  2749.     if (rc != NO_ERROR)
  2750.         return os2_error(rc);
  2751.  
  2752.     return Py_BuildValue("(ii)", read, write);
  2753. #else
  2754. #if !defined(MS_WIN32)
  2755.     int fds[2];
  2756.     int res;
  2757.     if (!PyArg_ParseTuple(args, ":pipe"))
  2758.         return NULL;
  2759.     Py_BEGIN_ALLOW_THREADS
  2760.     res = pipe(fds);
  2761.     Py_END_ALLOW_THREADS
  2762.     if (res != 0)
  2763.         return posix_error();
  2764.     return Py_BuildValue("(ii)", fds[0], fds[1]);
  2765. #else /* MS_WIN32 */
  2766.     HANDLE read, write;
  2767.     int read_fd, write_fd;
  2768.     BOOL ok;
  2769.     if (!PyArg_ParseTuple(args, ":pipe"))
  2770.         return NULL;
  2771.     Py_BEGIN_ALLOW_THREADS
  2772.     ok = CreatePipe(&read, &write, NULL, 0);
  2773.     Py_END_ALLOW_THREADS
  2774.     if (!ok)
  2775.         return posix_error();
  2776.     read_fd = _open_osfhandle((long)read, 0);
  2777.     write_fd = _open_osfhandle((long)write, 1);
  2778.     return Py_BuildValue("(ii)", read_fd, write_fd);
  2779. #endif /* MS_WIN32 */
  2780. #endif
  2781. }
  2782. #endif  /* HAVE_PIPE */
  2783.  
  2784.  
  2785. #ifdef HAVE_MKFIFO
  2786. static char posix_mkfifo__doc__[] =
  2787. "mkfifo(file, [, mode=0666]) -> None\n\
  2788. Create a FIFO (a POSIX named pipe).";
  2789.  
  2790. static PyObject *
  2791. posix_mkfifo(self, args)
  2792.     PyObject *self;
  2793.     PyObject *args;
  2794. {
  2795.     char *file;
  2796.     int mode = 0666;
  2797.     int res;
  2798.     if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
  2799.         return NULL;
  2800.     Py_BEGIN_ALLOW_THREADS
  2801.     res = mkfifo(file, mode);
  2802.     Py_END_ALLOW_THREADS
  2803.     if (res < 0)
  2804.         return posix_error();
  2805.     Py_INCREF(Py_None);
  2806.     return Py_None;
  2807. }
  2808. #endif
  2809.  
  2810.  
  2811. #ifdef HAVE_FTRUNCATE
  2812. static char posix_ftruncate__doc__[] =
  2813. "ftruncate(fd, length) -> None\n\
  2814. Truncate a file to a specified length.";
  2815.  
  2816. static PyObject *
  2817. posix_ftruncate(self, args)
  2818.     PyObject *self; /* Not used */
  2819.     PyObject *args;
  2820. {
  2821.     int fd;
  2822.     off_t length;
  2823.     int res;
  2824.     PyObject *lenobj;
  2825.  
  2826.     if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
  2827.         return NULL;
  2828.  
  2829. #if !defined(HAVE_LARGEFILE_SUPPORT)
  2830.     length = PyInt_AsLong(lenobj);
  2831. #else
  2832.     length = PyLong_Check(lenobj) ?
  2833.         PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
  2834. #endif
  2835.     if (PyErr_Occurred())
  2836.         return NULL;
  2837.  
  2838.     Py_BEGIN_ALLOW_THREADS
  2839.     res = ftruncate(fd, length);
  2840.     Py_END_ALLOW_THREADS
  2841.     if (res < 0) {
  2842.         PyErr_SetFromErrno(PyExc_IOError);
  2843.         return NULL;
  2844.     }
  2845.     Py_INCREF(Py_None);
  2846.     return Py_None;
  2847. }
  2848. #endif
  2849.  
  2850. #ifdef NeXT
  2851. #define HAVE_PUTENV
  2852. /* Steve Spicklemire got this putenv from NeXTAnswers */
  2853. static int
  2854. putenv(char *newval)
  2855. {
  2856.     extern char **environ;
  2857.  
  2858.     static int firstTime = 1;
  2859.     char **ep;
  2860.     char *cp;
  2861.     int esiz;
  2862.     char *np;
  2863.  
  2864.     if (!(np = strchr(newval, '=')))
  2865.         return 1;
  2866.     *np = '\0';
  2867.  
  2868.     /* look it up */
  2869.     for (ep=environ ; *ep ; ep++)
  2870.     {
  2871.         /* this should always be true... */
  2872.         if (cp = strchr(*ep, '='))
  2873.         {
  2874.             *cp = '\0';
  2875.             if (!strcmp(*ep, newval))
  2876.             {
  2877.                 /* got it! */
  2878.                 *cp = '=';
  2879.                 break;
  2880.             }
  2881.             *cp = '=';
  2882.         }
  2883.         else
  2884.         {
  2885.             *np = '=';
  2886.             return 1;
  2887.         }
  2888.     }
  2889.  
  2890.     *np = '=';
  2891.     if (*ep)
  2892.     {
  2893.         /* the string was already there:
  2894.            just replace it with the new one */
  2895.         *ep = newval;
  2896.         return 0;
  2897.     }
  2898.  
  2899.     /* expand environ by one */
  2900.     for (esiz=2, ep=environ ; *ep ; ep++)
  2901.         esiz++;
  2902.     if (firstTime)
  2903.     {
  2904.         char **epp;
  2905.         char **newenv;
  2906.         if (!(newenv = malloc(esiz * sizeof(char *))))
  2907.             return 1;
  2908.    
  2909.         for (ep=environ, epp=newenv ; *ep ;)
  2910.             *epp++ = *ep++;
  2911.         *epp++ = newval;
  2912.         *epp = (char *) 0;
  2913.         environ = newenv;
  2914.     }
  2915.     else
  2916.     {
  2917.         if (!(environ = realloc(environ, esiz * sizeof(char *))))
  2918.             return 1;
  2919.         environ[esiz - 2] = newval;
  2920.         environ[esiz - 1] = (char *) 0;
  2921.         firstTime = 0;
  2922.     }
  2923.  
  2924.     return 0;
  2925. }
  2926. #endif /* NeXT */
  2927.  
  2928.  
  2929. #ifdef HAVE_PUTENV
  2930. static char posix_putenv__doc__[] =
  2931. "putenv(key, value) -> None\n\
  2932. Change or add an environment variable.";
  2933.  
  2934. #ifdef __BEOS__
  2935. /* We have putenv(), but not in the headers (as of PR2). - [cjh] */
  2936. int putenv( const char *str );
  2937. #endif
  2938.  
  2939. /* Save putenv() parameters as values here, so we can collect them when they
  2940.  * get re-set with another call for the same key. */
  2941. static PyObject *posix_putenv_garbage;
  2942.  
  2943. static PyObject * 
  2944. posix_putenv(self, args)
  2945.     PyObject *self;
  2946.     PyObject *args;
  2947. {
  2948.         char *s1, *s2;
  2949.         char *new;
  2950.     PyObject *newstr;
  2951.  
  2952.     if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
  2953.         return NULL;
  2954.  
  2955. #if defined(PYOS_OS2)
  2956.     if (stricmp(s1, "BEGINLIBPATH") == 0) {
  2957.         APIRET rc;
  2958.  
  2959.         if (strlen(s2) == 0)  /* If New Value is an Empty String */
  2960.             s2 = NULL;        /* Then OS/2 API Wants a NULL to Undefine It */
  2961.  
  2962.         rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
  2963.         if (rc != NO_ERROR)
  2964.             return os2_error(rc);
  2965.  
  2966.     } else if (stricmp(s1, "ENDLIBPATH") == 0) {
  2967.         APIRET rc;
  2968.  
  2969.         if (strlen(s2) == 0)  /* If New Value is an Empty String */
  2970.             s2 = NULL;        /* Then OS/2 API Wants a NULL to Undefine It */
  2971.  
  2972.         rc = DosSetExtLIBPATH(s2, END_LIBPATH);
  2973.         if (rc != NO_ERROR)
  2974.             return os2_error(rc);
  2975.     } else {
  2976. #endif
  2977.  
  2978.     /* XXX This can leak memory -- not easy to fix :-( */
  2979.     newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
  2980.     if (newstr == NULL)
  2981.         return PyErr_NoMemory();
  2982.     new = PyString_AS_STRING(newstr);
  2983.     (void) sprintf(new, "%s=%s", s1, s2);
  2984.     if (putenv(new)) {
  2985.                 posix_error();
  2986.                 return NULL;
  2987.     }
  2988.     /* Install the first arg and newstr in posix_putenv_garbage;
  2989.      * this will cause previous value to be collected.  This has to
  2990.      * happen after the real putenv() call because the old value
  2991.      * was still accessible until then. */
  2992.     if (PyDict_SetItem(posix_putenv_garbage,
  2993.                PyTuple_GET_ITEM(args, 0), newstr)) {
  2994.         /* really not much we can do; just leak */
  2995.         PyErr_Clear();
  2996.     }
  2997.     else {
  2998.         Py_DECREF(newstr);
  2999.     }
  3000.  
  3001. #if defined(PYOS_OS2)
  3002.     }
  3003. #endif
  3004.     Py_INCREF(Py_None);
  3005.         return Py_None;
  3006. }
  3007. #endif /* putenv */
  3008.  
  3009. #ifdef HAVE_STRERROR
  3010. static char posix_strerror__doc__[] =
  3011. "strerror(code) -> string\n\
  3012. Translate an error code to a message string.";
  3013.  
  3014. PyObject *
  3015. posix_strerror(self, args)
  3016.     PyObject *self;
  3017.     PyObject *args;
  3018. {
  3019.     int code;
  3020.     char *message;
  3021.     if (!PyArg_ParseTuple(args, "i:strerror", &code))
  3022.         return NULL;
  3023.     message = strerror(code);
  3024.     if (message == NULL) {
  3025.         PyErr_SetString(PyExc_ValueError,
  3026.                 "strerror code out of range");
  3027.         return NULL;
  3028.     }
  3029.     return PyString_FromString(message);
  3030. }
  3031. #endif /* strerror */
  3032.  
  3033.  
  3034. #ifdef HAVE_SYS_WAIT_H
  3035.  
  3036. #ifdef WIFSTOPPED
  3037. static char posix_WIFSTOPPED__doc__[] =
  3038. "WIFSTOPPED(status) -> Boolean\n\
  3039. Return true if the process returning 'status' was stopped.";
  3040.  
  3041. static PyObject *
  3042. posix_WIFSTOPPED(self, args)
  3043.     PyObject *self;
  3044.     PyObject *args;
  3045. {
  3046. #ifdef UNION_WAIT
  3047.     union wait status;
  3048. #define status_i (status.w_status)
  3049. #else
  3050.     int status;
  3051. #define status_i status
  3052. #endif
  3053.     status_i = 0;
  3054.    
  3055.     if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
  3056.     {
  3057.         return NULL;
  3058.     }
  3059.    
  3060.     return Py_BuildValue("i", WIFSTOPPED(status));
  3061. #undef status_i
  3062. }
  3063. #endif /* WIFSTOPPED */
  3064.  
  3065. #ifdef WIFSIGNALED
  3066. static char posix_WIFSIGNALED__doc__[] =
  3067. "WIFSIGNALED(status) -> Boolean\n\
  3068. Return true if the process returning 'status' was terminated by a signal.";
  3069.  
  3070. static PyObject *
  3071. posix_WIFSIGNALED(self, args)
  3072.     PyObject *self;
  3073.     PyObject *args;
  3074. {
  3075. #ifdef UNION_WAIT
  3076.     union wait status;
  3077. #define status_i (status.w_status)
  3078. #else
  3079.     int status;
  3080. #define status_i status
  3081. #endif
  3082.     status_i = 0;
  3083.    
  3084.     if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
  3085.     {
  3086.         return NULL;
  3087.     }
  3088.    
  3089.     return Py_BuildValue("i", WIFSIGNALED(status));
  3090. #undef status_i
  3091. }
  3092. #endif /* WIFSIGNALED */
  3093.  
  3094. #ifdef WIFEXITED
  3095. static char posix_WIFEXITED__doc__[] =
  3096. "WIFEXITED(status) -> Boolean\n\
  3097. Return true if the process returning 'status' exited using the exit()\n\
  3098. system call.";
  3099.  
  3100. static PyObject *
  3101. posix_WIFEXITED(self, args)
  3102.     PyObject *self;
  3103.     PyObject *args;
  3104. {
  3105. #ifdef UNION_WAIT
  3106.     union wait status;
  3107. #define status_i (status.w_status)
  3108. #else
  3109.     int status;
  3110. #define status_i status
  3111. #endif
  3112.     status_i = 0;
  3113.    
  3114.     if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
  3115.     {
  3116.         return NULL;
  3117.     }
  3118.    
  3119.     return Py_BuildValue("i", WIFEXITED(status));
  3120. #undef status_i
  3121. }
  3122. #endif /* WIFEXITED */
  3123.  
  3124. #ifdef WEXITSTATUS
  3125. static char posix_WEXITSTATUS__doc__[] =
  3126. "WEXITSTATUS(status) -> integer\n\
  3127. Return the process return code from 'status'.";
  3128.  
  3129. static PyObject *
  3130. posix_WEXITSTATUS(self, args)
  3131.     PyObject *self;
  3132.     PyObject *args;
  3133. {
  3134. #ifdef UNION_WAIT
  3135.     union wait status;
  3136. #define status_i (status.w_status)
  3137. #else
  3138.     int status;
  3139. #define status_i status
  3140. #endif
  3141.     status_i = 0;
  3142.    
  3143.     if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
  3144.     {
  3145.         return NULL;
  3146.     }
  3147.    
  3148.     return Py_BuildValue("i", WEXITSTATUS(status));
  3149. #undef status_i
  3150. }
  3151. #endif /* WEXITSTATUS */
  3152.  
  3153. #ifdef WTERMSIG
  3154. static char posix_WTERMSIG__doc__[] =
  3155. "WTERMSIG(status) -> integer\n\
  3156. Return the signal that terminated the process that provided the 'status'\n\
  3157. value.";
  3158.  
  3159. static PyObject *
  3160. posix_WTERMSIG(self, args)
  3161.     PyObject *self;
  3162.     PyObject *args;
  3163. {
  3164. #ifdef UNION_WAIT
  3165.     union wait status;
  3166. #define status_i (status.w_status)
  3167. #else
  3168.     int status;
  3169. #define status_i status
  3170. #endif
  3171.     status_i = 0;
  3172.    
  3173.     if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
  3174.     {
  3175.         return NULL;
  3176.     }
  3177.    
  3178.     return Py_BuildValue("i", WTERMSIG(status));
  3179. #undef status_i
  3180. }
  3181. #endif /* WTERMSIG */
  3182.  
  3183. #ifdef WSTOPSIG
  3184. static char posix_WSTOPSIG__doc__[] =
  3185. "WSTOPSIG(status) -> integer\n\
  3186. Return the signal that stopped the process that provided the 'status' value.";
  3187.  
  3188. static PyObject *
  3189. posix_WSTOPSIG(self, args)
  3190.     PyObject *self;
  3191.     PyObject *args;
  3192. {
  3193. #ifdef UNION_WAIT
  3194.     union wait status;
  3195. #define status_i (status.w_status)
  3196. #else
  3197.     int status;
  3198. #define status_i status
  3199. #endif
  3200.     status_i = 0;
  3201.    
  3202.     if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
  3203.     {
  3204.         return NULL;
  3205.     }
  3206.    
  3207.     return Py_BuildValue("i", WSTOPSIG(status));
  3208. #undef status_i
  3209. }
  3210. #endif /* WSTOPSIG */
  3211.  
  3212. #endif /* HAVE_SYS_WAIT_H */
  3213.  
  3214.  
  3215. #if defined(HAVE_FSTATVFS)
  3216. #ifdef _SCO_DS
  3217. /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
  3218.    needed definitions in sys/statvfs.h */
  3219. #define _SVID3
  3220. #endif
  3221. #include <sys/statvfs.h>
  3222.  
  3223. static char posix_fstatvfs__doc__[] =
  3224. "fstatvfs(fd) -> \n\
  3225.  (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
  3226. Perform an fstatvfs system call on the given fd.";
  3227.  
  3228. static PyObject *
  3229. posix_fstatvfs(self, args)
  3230.     PyObject *self;
  3231.     PyObject *args;
  3232. {
  3233.     int fd, res;
  3234.     struct statvfs st;
  3235.     if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
  3236.         return NULL;
  3237.     Py_BEGIN_ALLOW_THREADS
  3238.     res = fstatvfs(fd, &st);
  3239.     Py_END_ALLOW_THREADS
  3240.     if (res != 0)
  3241.         return posix_error();
  3242. #if !defined(HAVE_LARGEFILE_SUPPORT)
  3243.     return Py_BuildValue("(llllllllll)",
  3244.             (long) st.f_bsize,
  3245.             (long) st.f_frsize,
  3246.             (long) st.f_blocks,
  3247.             (long) st.f_bfree,
  3248.             (long) st.f_bavail,
  3249.             (long) st.f_files,
  3250.             (long) st.f_ffree,
  3251.             (long) st.f_favail,
  3252.             (long) st.f_flag,
  3253.             (long) st.f_namemax);
  3254. #else
  3255.     return Py_BuildValue("(llLLLLLLll)",
  3256.             (long) st.f_bsize,
  3257.             (long) st.f_frsize,
  3258.             (LONG_LONG) st.f_blocks,
  3259.             (LONG_LONG) st.f_bfree,
  3260.             (LONG_LONG) st.f_bavail,
  3261.             (LONG_LONG) st.f_files,
  3262.             (LONG_LONG) st.f_ffree,
  3263.             (LONG_LONG) st.f_favail,
  3264.             (long) st.f_flag,
  3265.             (long) st.f_namemax);
  3266. #endif
  3267. }
  3268. #endif /* HAVE_FSTATVFS */
  3269.  
  3270.  
  3271. #if defined(HAVE_STATVFS)
  3272. #include <sys/statvfs.h>
  3273.  
  3274. static char posix_statvfs__doc__[] =
  3275. "statvfs(path) -> \n\
  3276.  (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
  3277. Perform a statvfs system call on the given path.";
  3278.  
  3279. static PyObject *
  3280. posix_statvfs(self, args)
  3281.     PyObject *self;
  3282.     PyObject *args;
  3283. {
  3284.     char *path;
  3285.     int res;
  3286.     struct statvfs st;
  3287.     if (!PyArg_ParseTuple(args, "s:statvfs", &path))
  3288.         return NULL;
  3289.     Py_BEGIN_ALLOW_THREADS
  3290.     res = statvfs(path, &st);
  3291.     Py_END_ALLOW_THREADS
  3292.     if (res != 0)
  3293.         return posix_error_with_filename(path);
  3294. #if !defined(HAVE_LARGEFILE_SUPPORT)
  3295.     return Py_BuildValue("(llllllllll)",
  3296.             (long) st.f_bsize,
  3297.             (long) st.f_frsize,
  3298.             (long) st.f_blocks,
  3299.             (long) st.f_bfree,
  3300.             (long) st.f_bavail,
  3301.             (long) st.f_files,
  3302.             (long) st.f_ffree,
  3303.             (long) st.f_favail,
  3304.             (long) st.f_flag,
  3305.             (long) st.f_namemax);
  3306. #else    /* HAVE_LARGEFILE_SUPPORT */
  3307.     return Py_BuildValue("(llLLLLLLll)",
  3308.             (long) st.f_bsize,
  3309.             (long) st.f_frsize,
  3310.             (LONG_LONG) st.f_blocks,
  3311.             (LONG_LONG) st.f_bfree,
  3312.             (LONG_LONG) st.f_bavail,
  3313.             (LONG_LONG) st.f_files,
  3314.             (LONG_LONG) st.f_ffree,
  3315.             (LONG_LONG) st.f_favail,
  3316.             (long) st.f_flag,
  3317.             (long) st.f_namemax);
  3318. #endif
  3319. }
  3320. #endif /* HAVE_STATVFS */
  3321.  
  3322.  
  3323. #ifdef HAVE_TEMPNAM
  3324. static char posix_tempnam__doc__[] = "\
  3325. tempnam([dir[, prefix]]) -> string\n\
  3326. Return a unique name for a temporary file.\n\
  3327. The directory and a short may be specified as strings; they may be omitted\n\
  3328. or None if not needed.";
  3329.  
  3330. static PyObject *
  3331. posix_tempnam(self, args)
  3332.      PyObject *self;
  3333.      PyObject *args;
  3334. {
  3335.     PyObject *result = NULL;
  3336.     char *dir = NULL;
  3337.     char *pfx = NULL;
  3338.     char *name;
  3339.  
  3340.     if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
  3341.         return NULL;
  3342.     name = tempnam(dir, pfx);
  3343.     if (name == NULL)
  3344.         return PyErr_NoMemory();
  3345.     result = PyString_FromString(name);
  3346.     free(name);
  3347.     return result;
  3348. }
  3349. #endif
  3350.  
  3351.  
  3352. #ifdef HAVE_TMPFILE
  3353. static char posix_tmpfile__doc__[] = "\
  3354. tmpfile() -> file object\n\
  3355. Create a temporary file with no directory entries.";
  3356.  
  3357. static PyObject *
  3358. posix_tmpfile(self, args)
  3359.      PyObject *self;
  3360.      PyObject *args;
  3361. {
  3362.     FILE *fp;
  3363.  
  3364.     if (!PyArg_ParseTuple(args, ":tmpfile"))
  3365.         return NULL;
  3366.     fp = tmpfile();
  3367.     if (fp == NULL)
  3368.         return posix_error();
  3369.     return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
  3370. }
  3371. #endif
  3372.  
  3373.  
  3374. #ifdef HAVE_TMPNAM
  3375. static char posix_tmpnam__doc__[] = "\
  3376. tmpnam() -> string\n\
  3377. Return a unique name for a temporary file.";
  3378.  
  3379. static PyObject *
  3380. posix_tmpnam(self, args)
  3381.      PyObject *self;
  3382.      PyObject *args;
  3383. {
  3384.     char buffer[L_tmpnam];
  3385.     char *name;
  3386.  
  3387.     if (!PyArg_ParseTuple(args, ":tmpnam"))
  3388.         return NULL;
  3389. #ifdef USE_TMPNAM_R
  3390.     name = tmpnam_r(buffer);
  3391. #else
  3392.     name = tmpnam(buffer);
  3393. #endif
  3394.     if (name == NULL) {
  3395.         PyErr_SetObject(PyExc_OSError,
  3396.                         Py_BuildValue("is", 0,
  3397. #ifdef USE_TMPNAM_R
  3398.                                       "unexpected NULL from tmpnam_r"
  3399. #else
  3400.                                       "unexpected NULL from tmpnam"
  3401. #endif
  3402.                                       ));
  3403.         return NULL;
  3404.     }
  3405.     return PyString_FromString(buffer);
  3406. }
  3407. #endif
  3408.  
  3409.  
  3410. /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
  3411.  * It maps strings representing configuration variable names to
  3412.  * integer values, allowing those functions to be called with the
  3413.  * magic names instead of poluting the module's namespace with tons of
  3414.  * rarely-used constants.  There are three separate tables that use
  3415.  * these definitions.
  3416.  *
  3417.  * This code is always included, even if none of the interfaces that
  3418.  * need it are included.  The #if hackery needed to avoid it would be
  3419.  * sufficiently pervasive that it's not worth the loss of readability.
  3420.  */
  3421. struct constdef {
  3422.     char *name;
  3423.     long value;
  3424. };
  3425.  
  3426. static int
  3427. conv_confname(arg, valuep, table, tablesize)
  3428.      PyObject *arg;
  3429.      int *valuep;
  3430.      struct constdef *table;
  3431.      size_t tablesize;
  3432. {
  3433.     if (PyInt_Check(arg)) {
  3434.         *valuep = PyInt_AS_LONG(arg);
  3435.         return 1;
  3436.     }
  3437.     if (PyString_Check(arg)) {
  3438.         /* look up the value in the table using a binary search */
  3439.         int lo = 0;
  3440.         int hi = tablesize;
  3441.         int cmp, mid;
  3442.         char *confname = PyString_AS_STRING(arg);
  3443.         while (lo < hi) {
  3444.             mid = (lo + hi) / 2;
  3445.             cmp = strcmp(confname, table[mid].name);
  3446.             if (cmp < 0)
  3447.                 hi = mid;
  3448.             else if (cmp > 0)
  3449.                 lo = mid + 1;
  3450.             else {
  3451.                 *valuep = table[mid].value;
  3452.                 return 1;
  3453.             }
  3454.         }
  3455.         PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
  3456.     }
  3457.     else
  3458.         PyErr_SetString(PyExc_TypeError,
  3459.                         "configuration names must be strings or integers");
  3460.     return 0;
  3461. }
  3462.  
  3463.  
  3464. #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
  3465. static struct constdef  posix_constants_pathconf[] = {
  3466. #ifdef _PC_ABI_AIO_XFER_MAX
  3467.     {"PC_ABI_AIO_XFER_MAX",    _PC_ABI_AIO_XFER_MAX},
  3468. #endif
  3469. #ifdef _PC_ABI_ASYNC_IO
  3470.     {"PC_ABI_ASYNC_IO",    _PC_ABI_ASYNC_IO},
  3471. #endif
  3472. #ifdef _PC_ASYNC_IO
  3473.     {"PC_ASYNC_IO",    _PC_ASYNC_IO},
  3474. #endif
  3475. #ifdef _PC_CHOWN_RESTRICTED
  3476.     {"PC_CHOWN_RESTRICTED",    _PC_CHOWN_RESTRICTED},
  3477. #endif
  3478. #ifdef _PC_FILESIZEBITS
  3479.     {"PC_FILESIZEBITS",    _PC_FILESIZEBITS},
  3480. #endif
  3481. #ifdef _PC_LAST
  3482.     {"PC_LAST",    _PC_LAST},
  3483. #endif
  3484. #ifdef _PC_LINK_MAX
  3485.     {"PC_LINK_MAX",    _PC_LINK_MAX},
  3486. #endif
  3487. #ifdef _PC_MAX_CANON
  3488.     {"PC_MAX_CANON",    _PC_MAX_CANON},
  3489. #endif
  3490. #ifdef _PC_MAX_INPUT
  3491.     {"PC_MAX_INPUT",    _PC_MAX_INPUT},
  3492. #endif
  3493. #ifdef _PC_NAME_MAX
  3494.     {"PC_NAME_MAX",    _PC_NAME_MAX},
  3495. #endif
  3496. #ifdef _PC_NO_TRUNC
  3497.     {"PC_NO_TRUNC",    _PC_NO_TRUNC},
  3498. #endif
  3499. #ifdef _PC_PATH_MAX
  3500.     {"PC_PATH_MAX",    _PC_PATH_MAX},
  3501. #endif
  3502. #ifdef _PC_PIPE_BUF
  3503.     {"PC_PIPE_BUF",    _PC_PIPE_BUF},
  3504. #endif
  3505. #ifdef _PC_PRIO_IO
  3506.     {"PC_PRIO_IO",    _PC_PRIO_IO},
  3507. #endif
  3508. #ifdef _PC_SOCK_MAXBUF
  3509.     {"PC_SOCK_MAXBUF",    _PC_SOCK_MAXBUF},
  3510. #endif
  3511. #ifdef _PC_SYNC_IO
  3512.     {"PC_SYNC_IO",    _PC_SYNC_IO},
  3513. #endif
  3514. #ifdef _PC_VDISABLE
  3515.     {"PC_VDISABLE",    _PC_VDISABLE},
  3516. #endif
  3517. };
  3518.  
  3519. static int
  3520. conv_path_confname(arg, valuep)
  3521.      PyObject *arg;
  3522.      int *valuep;
  3523. {
  3524.     return conv_confname(arg, valuep, posix_constants_pathconf,
  3525.                          sizeof(posix_constants_pathconf)
  3526.                            / sizeof(struct constdef));
  3527. }
  3528. #endif
  3529.  
  3530. #ifdef HAVE_FPATHCONF
  3531. static char posix_fpathconf__doc__[] = "\
  3532. fpathconf(fd, name) -> integer\n\
  3533. Return the configuration limit name for the file descriptor fd.\n\
  3534. If there is no limit, return -1.";
  3535.  
  3536. static PyObject *
  3537. posix_fpathconf(self, args)
  3538.      PyObject *self;
  3539.      PyObject *args;
  3540. {
  3541.     PyObject *result = NULL;
  3542.     int name, fd;
  3543.  
  3544.     if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
  3545.                          conv_path_confname, &name)) {
  3546.         long limit;
  3547.  
  3548.         errno = 0;
  3549.         limit = fpathconf(fd, name);
  3550.         if (limit == -1 && errno != 0)
  3551.             posix_error();
  3552.         else
  3553.             result = PyInt_FromLong(limit);
  3554.     }
  3555.     return result;
  3556. }
  3557. #endif
  3558.  
  3559.  
  3560. #ifdef HAVE_PATHCONF
  3561. static char posix_pathconf__doc__[] = "\
  3562. pathconf(path, name) -> integer\n\
  3563. Return the configuration limit name for the file or directory path.\n\
  3564. If there is no limit, return -1.";
  3565.  
  3566. static PyObject *
  3567. posix_pathconf(self, args)
  3568.      PyObject *self;
  3569.      PyObject *args;
  3570. {
  3571.     PyObject *result = NULL;
  3572.     int name;
  3573.     char *path;
  3574.  
  3575.     if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
  3576.                          conv_path_confname, &name)) {
  3577.         long limit;
  3578.  
  3579.         errno = 0;
  3580.         limit = pathconf(path, name);
  3581.         if (limit == -1 && errno != 0) {
  3582.             if (errno == EINVAL)
  3583.                 /* could be a path or name problem */
  3584.                 posix_error();
  3585.             else
  3586.                 posix_error_with_filename(path);
  3587.         }
  3588.         else
  3589.             result = PyInt_FromLong(limit);
  3590.     }
  3591.     return result;
  3592. }
  3593. #endif
  3594.  
  3595. #ifdef HAVE_CONFSTR
  3596. static struct constdef posix_constants_confstr[] = {
  3597. #ifdef _CS_ARCHITECTURE
  3598.     {"CS_ARCHITECTURE",    _CS_ARCHITECTURE},
  3599. #endif
  3600. #ifdef _CS_HOSTNAME
  3601.     {"CS_HOSTNAME",    _CS_HOSTNAME},
  3602. #endif
  3603. #ifdef _CS_HW_PROVIDER
  3604.     {"CS_HW_PROVIDER",    _CS_HW_PROVIDER},
  3605. #endif
  3606. #ifdef _CS_HW_SERIAL
  3607.     {"CS_HW_SERIAL",    _CS_HW_SERIAL},
  3608. #endif
  3609. #ifdef _CS_INITTAB_NAME
  3610.     {"CS_INITTAB_NAME",    _CS_INITTAB_NAME},
  3611. #endif
  3612. #ifdef _CS_LFS64_CFLAGS
  3613.     {"CS_LFS64_CFLAGS",    _CS_LFS64_CFLAGS},
  3614. #endif
  3615. #ifdef _CS_LFS64_LDFLAGS
  3616.     {"CS_LFS64_LDFLAGS",    _CS_LFS64_LDFLAGS},
  3617. #endif
  3618. #ifdef _CS_LFS64_LIBS
  3619.     {"CS_LFS64_LIBS",    _CS_LFS64_LIBS},
  3620. #endif
  3621. #ifdef _CS_LFS64_LINTFLAGS
  3622.     {"CS_LFS64_LINTFLAGS",    _CS_LFS64_LINTFLAGS},
  3623. #endif
  3624. #ifdef _CS_LFS_CFLAGS
  3625.     {"CS_LFS_CFLAGS",    _CS_LFS_CFLAGS},
  3626. #endif
  3627. #ifdef _CS_LFS_LDFLAGS
  3628.     {"CS_LFS_LDFLAGS",    _CS_LFS_LDFLAGS},
  3629. #endif
  3630. #ifdef _CS_LFS_LIBS
  3631.     {"CS_LFS_LIBS",    _CS_LFS_LIBS},
  3632. #endif
  3633. #ifdef _CS_LFS_LINTFLAGS
  3634.     {"CS_LFS_LINTFLAGS",    _CS_LFS_LINTFLAGS},
  3635. #endif
  3636. #ifdef _CS_MACHINE
  3637.     {"CS_MACHINE",    _CS_MACHINE},
  3638. #endif
  3639. #ifdef _CS_PATH
  3640.     {"CS_PATH",    _CS_PATH},
  3641. #endif
  3642. #ifdef _CS_RELEASE
  3643.     {"CS_RELEASE",    _CS_RELEASE},
  3644. #endif
  3645. #ifdef _CS_SRPC_DOMAIN
  3646.     {"CS_SRPC_DOMAIN",    _CS_SRPC_DOMAIN},
  3647. #endif
  3648. #ifdef _CS_SYSNAME
  3649.     {"CS_SYSNAME",    _CS_SYSNAME},
  3650. #endif
  3651. #ifdef _CS_VERSION
  3652.     {"CS_VERSION",    _CS_VERSION},
  3653. #endif
  3654. #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
  3655.     {"CS_XBS5_ILP32_OFF32_CFLAGS",    _CS_XBS5_ILP32_OFF32_CFLAGS},
  3656. #endif
  3657. #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
  3658.     {"CS_XBS5_ILP32_OFF32_LDFLAGS",    _CS_XBS5_ILP32_OFF32_LDFLAGS},
  3659. #endif
  3660. #ifdef _CS_XBS5_ILP32_OFF32_LIBS
  3661.     {"CS_XBS5_ILP32_OFF32_LIBS",    _CS_XBS5_ILP32_OFF32_LIBS},
  3662. #endif
  3663. #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
  3664.     {"CS_XBS5_ILP32_OFF32_LINTFLAGS",    _CS_XBS5_ILP32_OFF32_LINTFLAGS},
  3665. #endif
  3666. #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
  3667.     {"CS_XBS5_ILP32_OFFBIG_CFLAGS",    _CS_XBS5_ILP32_OFFBIG_CFLAGS},
  3668. #endif
  3669. #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
  3670.     {"CS_XBS5_ILP32_OFFBIG_LDFLAGS",    _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
  3671. #endif
  3672. #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
  3673.     {"CS_XBS5_ILP32_OFFBIG_LIBS",    _CS_XBS5_ILP32_OFFBIG_LIBS},
  3674. #endif
  3675. #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
  3676.     {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS",    _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
  3677. #endif
  3678. #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
  3679.     {"CS_XBS5_LP64_OFF64_CFLAGS",    _CS_XBS5_LP64_OFF64_CFLAGS},
  3680. #endif
  3681. #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
  3682.     {"CS_XBS5_LP64_OFF64_LDFLAGS",    _CS_XBS5_LP64_OFF64_LDFLAGS},
  3683. #endif
  3684. #ifdef _CS_XBS5_LP64_OFF64_LIBS
  3685.     {"CS_XBS5_LP64_OFF64_LIBS",    _CS_XBS5_LP64_OFF64_LIBS},
  3686. #endif
  3687. #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
  3688.     {"CS_XBS5_LP64_OFF64_LINTFLAGS",    _CS_XBS5_LP64_OFF64_LINTFLAGS},
  3689. #endif
  3690. #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
  3691.     {"CS_XBS5_LPBIG_OFFBIG_CFLAGS",    _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
  3692. #endif
  3693. #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
  3694.     {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS",    _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
  3695. #endif
  3696. #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
  3697.     {"CS_XBS5_LPBIG_OFFBIG_LIBS",    _CS_XBS5_LPBIG_OFFBIG_LIBS},
  3698. #endif
  3699. #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
  3700.     {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS",    _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
  3701. #endif
  3702. #ifdef _MIPS_CS_AVAIL_PROCESSORS
  3703.     {"MIPS_CS_AVAIL_PROCESSORS",    _MIPS_CS_AVAIL_PROCESSORS},
  3704. #endif
  3705. #ifdef _MIPS_CS_BASE
  3706.     {"MIPS_CS_BASE",    _MIPS_CS_BASE},
  3707. #endif
  3708. #ifdef _MIPS_CS_HOSTID
  3709.     {"MIPS_CS_HOSTID",    _MIPS_CS_HOSTID},
  3710. #endif
  3711. #ifdef _MIPS_CS_HW_NAME
  3712.     {"MIPS_CS_HW_NAME",    _MIPS_CS_HW_NAME},
  3713. #endif
  3714. #ifdef _MIPS_CS_NUM_PROCESSORS
  3715.     {"MIPS_CS_NUM_PROCESSORS",    _MIPS_CS_NUM_PROCESSORS},
  3716. #endif
  3717. #ifdef _MIPS_CS_OSREL_MAJ
  3718.     {"MIPS_CS_OSREL_MAJ",    _MIPS_CS_OSREL_MAJ},
  3719. #endif
  3720. #ifdef _MIPS_CS_OSREL_MIN
  3721.     {"MIPS_CS_OSREL_MIN",    _MIPS_CS_OSREL_MIN},
  3722. #endif
  3723. #ifdef _MIPS_CS_OSREL_PATCH
  3724.     {"MIPS_CS_OSREL_PATCH",    _MIPS_CS_OSREL_PATCH},
  3725. #endif
  3726. #ifdef _MIPS_CS_OS_NAME
  3727.     {"MIPS_CS_OS_NAME",    _MIPS_CS_OS_NAME},
  3728. #endif
  3729. #ifdef _MIPS_CS_OS_PROVIDER
  3730.     {"MIPS_CS_OS_PROVIDER",    _MIPS_CS_OS_PROVIDER},
  3731. #endif
  3732. #ifdef _MIPS_CS_PROCESSORS
  3733.     {"MIPS_CS_PROCESSORS",    _MIPS_CS_PROCESSORS},
  3734. #endif
  3735. #ifdef _MIPS_CS_SERIAL
  3736.     {"MIPS_CS_SERIAL",    _MIPS_CS_SERIAL},
  3737. #endif
  3738. #ifdef _MIPS_CS_VENDOR
  3739.     {"MIPS_CS_VENDOR",    _MIPS_CS_VENDOR},
  3740. #endif
  3741. };
  3742.  
  3743. static int
  3744. conv_confstr_confname(arg, valuep)
  3745.      PyObject *arg;
  3746.      int *valuep;
  3747. {
  3748.     return conv_confname(arg, valuep, posix_constants_confstr,
  3749.                          sizeof(posix_constants_confstr)
  3750.                            / sizeof(struct constdef));
  3751. }
  3752.  
  3753. static char posix_confstr__doc__[] = "\
  3754. confstr(name) -> string\n\
  3755. Return a string-valued system configuration variable.";
  3756.  
  3757. static PyObject *
  3758. posix_confstr(self, args)
  3759.      PyObject *self;
  3760.      PyObject *args;
  3761. {
  3762.     PyObject *result = NULL;
  3763.     int name;
  3764.     char buffer[64];
  3765.  
  3766.     if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
  3767.         int len = confstr(name, buffer, sizeof(buffer));
  3768.  
  3769.         errno = 0;
  3770.         if (len == 0) {
  3771.             if (errno != 0)
  3772.                 posix_error();
  3773.             else
  3774.                 result = PyString_FromString("");
  3775.         }
  3776.         else {
  3777.             if (len >= sizeof(buffer)) {
  3778.                 result = PyString_FromStringAndSize(NULL, len);
  3779.                 if (result != NULL)
  3780.                     confstr(name, PyString_AS_STRING(result), len+1);
  3781.             }
  3782.             else
  3783.                 result = PyString_FromString(buffer);
  3784.         }
  3785.     }
  3786.     return result;
  3787. }
  3788. #endif
  3789.  
  3790.  
  3791. #ifdef HAVE_SYSCONF
  3792. static struct constdef posix_constants_sysconf[] = {
  3793. #ifdef _SC_2_CHAR_TERM
  3794.     {"SC_2_CHAR_TERM",    _SC_2_CHAR_TERM},
  3795. #endif
  3796. #ifdef _SC_2_C_BIND
  3797.     {"SC_2_C_BIND",    _SC_2_C_BIND},
  3798. #endif
  3799. #ifdef _SC_2_C_DEV
  3800.     {"SC_2_C_DEV",    _SC_2_C_DEV},
  3801. #endif
  3802. #ifdef _SC_2_C_VERSION
  3803.     {"SC_2_C_VERSION",    _SC_2_C_VERSION},
  3804. #endif
  3805. #ifdef _SC_2_FORT_DEV
  3806.     {"SC_2_FORT_DEV",    _SC_2_FORT_DEV},
  3807. #endif
  3808. #ifdef _SC_2_FORT_RUN
  3809.     {"SC_2_FORT_RUN",    _SC_2_FORT_RUN},
  3810. #endif
  3811. #ifdef _SC_2_LOCALEDEF
  3812.     {"SC_2_LOCALEDEF",    _SC_2_LOCALEDEF},
  3813. #endif
  3814. #ifdef _SC_2_SW_DEV
  3815.     {"SC_2_SW_DEV",    _SC_2_SW_DEV},
  3816. #endif
  3817. #ifdef _SC_2_UPE
  3818.     {"SC_2_UPE",    _SC_2_UPE},
  3819. #endif
  3820. #ifdef _SC_2_VERSION
  3821.     {"SC_2_VERSION",    _SC_2_VERSION},
  3822. #endif
  3823. #ifdef _SC_ABI_ASYNCHRONOUS_IO
  3824.     {"SC_ABI_ASYNCHRONOUS_IO",    _SC_ABI_ASYNCHRONOUS_IO},
  3825. #endif
  3826. #ifdef _SC_ACL
  3827.     {"SC_ACL",    _SC_ACL},
  3828. #endif
  3829. #ifdef _SC_AIO_LISTIO_MAX
  3830.     {"SC_AIO_LISTIO_MAX",    _SC_AIO_LISTIO_MAX},
  3831. #endif
  3832. #ifdef _SC_AIO_MAX
  3833.     {"SC_AIO_MAX",    _SC_AIO_MAX},
  3834. #endif
  3835. #ifdef _SC_AIO_PRIO_DELTA_MAX
  3836.     {"SC_AIO_PRIO_DELTA_MAX",    _SC_AIO_PRIO_DELTA_MAX},
  3837. #endif
  3838. #ifdef _SC_ARG_MAX
  3839.     {"SC_ARG_MAX",    _SC_ARG_MAX},
  3840. #endif
  3841. #ifdef _SC_ASYNCHRONOUS_IO
  3842.     {"SC_ASYNCHRONOUS_IO",    _SC_ASYNCHRONOUS_IO},
  3843. #endif
  3844. #ifdef _SC_ATEXIT_MAX
  3845.     {"SC_ATEXIT_MAX",    _SC_ATEXIT_MAX},
  3846. #endif
  3847. #ifdef _SC_AUDIT
  3848.     {"SC_AUDIT",    _SC_AUDIT},
  3849. #endif
  3850. #ifdef _SC_AVPHYS_PAGES
  3851.     {"SC_AVPHYS_PAGES",    _SC_AVPHYS_PAGES},
  3852. #endif
  3853. #ifdef _SC_BC_BASE_MAX
  3854.     {"SC_BC_BASE_MAX",    _SC_BC_BASE_MAX},
  3855. #endif
  3856. #ifdef _SC_BC_DIM_MAX
  3857.     {"SC_BC_DIM_MAX",    _SC_BC_DIM_MAX},
  3858. #endif
  3859. #ifdef _SC_BC_SCALE_MAX
  3860.     {"SC_BC_SCALE_MAX",    _SC_BC_SCALE_MAX},
  3861. #endif
  3862. #ifdef _SC_BC_STRING_MAX
  3863.     {"SC_BC_STRING_MAX",    _SC_BC_STRING_MAX},
  3864. #endif
  3865. #ifdef _SC_CAP
  3866.     {"SC_CAP",    _SC_CAP},
  3867. #endif
  3868. #ifdef _SC_CHARCLASS_NAME_MAX
  3869.     {"SC_CHARCLASS_NAME_MAX",    _SC_CHARCLASS_NAME_MAX},
  3870. #endif
  3871. #ifdef _SC_CHAR_BIT
  3872.     {"SC_CHAR_BIT",    _SC_CHAR_BIT},
  3873. #endif
  3874. #ifdef _SC_CHAR_MAX
  3875.     {"SC_CHAR_MAX",    _SC_CHAR_MAX},
  3876. #endif
  3877. #ifdef _SC_CHAR_MIN
  3878.     {"SC_CHAR_MIN",    _SC_CHAR_MIN},
  3879. #endif
  3880. #ifdef _SC_CHILD_MAX
  3881.     {"SC_CHILD_MAX",    _SC_CHILD_MAX},
  3882. #endif
  3883. #ifdef _SC_CLK_TCK
  3884.     {"SC_CLK_TCK",    _SC_CLK_TCK},
  3885. #endif
  3886. #ifdef _SC_COHER_BLKSZ
  3887.     {"SC_COHER_BLKSZ",    _SC_COHER_BLKSZ},
  3888. #endif
  3889. #ifdef _SC_COLL_WEIGHTS_MAX
  3890.     {"SC_COLL_WEIGHTS_MAX",    _SC_COLL_WEIGHTS_MAX},
  3891. #endif
  3892. #ifdef _SC_DCACHE_ASSOC
  3893.     {"SC_DCACHE_ASSOC",    _SC_DCACHE_ASSOC},
  3894. #endif
  3895. #ifdef _SC_DCACHE_BLKSZ
  3896.     {"SC_DCACHE_BLKSZ",    _SC_DCACHE_BLKSZ},
  3897. #endif
  3898. #ifdef _SC_DCACHE_LINESZ
  3899.     {"SC_DCACHE_LINESZ",    _SC_DCACHE_LINESZ},
  3900. #endif
  3901. #ifdef _SC_DCACHE_SZ
  3902.     {"SC_DCACHE_SZ",    _SC_DCACHE_SZ},
  3903. #endif
  3904. #ifdef _SC_DCACHE_TBLKSZ
  3905.     {"SC_DCACHE_TBLKSZ",    _SC_DCACHE_TBLKSZ},
  3906. #endif
  3907. #ifdef _SC_DELAYTIMER_MAX
  3908.     {"SC_DELAYTIMER_MAX",    _SC_DELAYTIMER_MAX},
  3909. #endif
  3910. #ifdef _SC_EQUIV_CLASS_MAX
  3911.     {"SC_EQUIV_CLASS_MAX",    _SC_EQUIV_CLASS_MAX},
  3912. #endif
  3913. #ifdef _SC_EXPR_NEST_MAX
  3914.     {"SC_EXPR_NEST_MAX",    _SC_EXPR_NEST_MAX},
  3915. #endif
  3916. #ifdef _SC_FSYNC
  3917.     {"SC_FSYNC",    _SC_FSYNC},
  3918. #endif
  3919. #ifdef _SC_GETGR_R_SIZE_MAX
  3920.     {"SC_GETGR_R_SIZE_MAX",    _SC_GETGR_R_SIZE_MAX},
  3921. #endif
  3922. #ifdef _SC_GETPW_R_SIZE_MAX
  3923.     {"SC_GETPW_R_SIZE_MAX",    _SC_GETPW_R_SIZE_MAX},
  3924. #endif
  3925. #ifdef _SC_ICACHE_ASSOC
  3926.     {"SC_ICACHE_ASSOC",    _SC_ICACHE_ASSOC},
  3927. #endif
  3928. #ifdef _SC_ICACHE_BLKSZ
  3929.     {"SC_ICACHE_BLKSZ",    _SC_ICACHE_BLKSZ},
  3930. #endif
  3931. #ifdef _SC_ICACHE_LINESZ
  3932.     {"SC_ICACHE_LINESZ",    _SC_ICACHE_LINESZ},
  3933. #endif
  3934. #ifdef _SC_ICACHE_SZ
  3935.     {"SC_ICACHE_SZ",    _SC_ICACHE_SZ},
  3936. #endif
  3937. #ifdef _SC_INF
  3938.     {"SC_INF",    _SC_INF},
  3939. #endif
  3940. #ifdef _SC_INT_MAX
  3941.     {"SC_INT_MAX",    _SC_INT_MAX},
  3942. #endif
  3943. #ifdef _SC_INT_MIN
  3944.     {"SC_INT_MIN",    _SC_INT_MIN},
  3945. #endif
  3946. #ifdef _SC_IOV_MAX
  3947.     {"SC_IOV_MAX",    _SC_IOV_MAX},
  3948. #endif
  3949. #ifdef _SC_IP_SECOPTS
  3950.     {"SC_IP_SECOPTS",    _SC_IP_SECOPTS},
  3951. #endif
  3952. #ifdef _SC_JOB_CONTROL
  3953.     {"SC_JOB_CONTROL",    _SC_JOB_CONTROL},
  3954. #endif
  3955. #ifdef _SC_KERN_POINTERS
  3956.     {"SC_KERN_POINTERS",    _SC_KERN_POINTERS},
  3957. #endif
  3958. #ifdef _SC_KERN_SIM
  3959.     {"SC_KERN_SIM",    _SC_KERN_SIM},
  3960. #endif
  3961. #ifdef _SC_LINE_MAX
  3962.     {"SC_LINE_MAX",    _SC_LINE_MAX},
  3963. #endif
  3964. #ifdef _SC_LOGIN_NAME_MAX
  3965.     {"SC_LOGIN_NAME_MAX",    _SC_LOGIN_NAME_MAX},
  3966. #endif
  3967. #ifdef _SC_LOGNAME_MAX
  3968.     {"SC_LOGNAME_MAX",    _SC_LOGNAME_MAX},
  3969. #endif
  3970. #ifdef _SC_LONG_BIT
  3971.     {"SC_LONG_BIT",    _SC_LONG_BIT},
  3972. #endif
  3973. #ifdef _SC_MAC
  3974.     {"SC_MAC",    _SC_MAC},
  3975. #endif
  3976. #ifdef _SC_MAPPED_FILES
  3977.     {"SC_MAPPED_FILES",    _SC_MAPPED_FILES},
  3978. #endif
  3979. #ifdef _SC_MAXPID
  3980.     {"SC_MAXPID",    _SC_MAXPID},
  3981. #endif
  3982. #ifdef _SC_MB_LEN_MAX
  3983.     {"SC_MB_LEN_MAX",    _SC_MB_LEN_MAX},
  3984. #endif
  3985. #ifdef _SC_MEMLOCK
  3986.     {"SC_MEMLOCK",    _SC_MEMLOCK},
  3987. #endif
  3988. #ifdef _SC_MEMLOCK_RANGE
  3989.     {"SC_MEMLOCK_RANGE",    _SC_MEMLOCK_RANGE},
  3990. #endif
  3991. #ifdef _SC_MEMORY_PROTECTION
  3992.     {"SC_MEMORY_PROTECTION",    _SC_MEMORY_PROTECTION},
  3993. #endif
  3994. #ifdef _SC_MESSAGE_PASSING
  3995.     {"SC_MESSAGE_PASSING",    _SC_MESSAGE_PASSING},
  3996. #endif
  3997. #ifdef _SC_MMAP_FIXED_ALIGNMENT
  3998.     {"SC_MMAP_FIXED_ALIGNMENT",    _SC_MMAP_FIXED_ALIGNMENT},
  3999. #endif
  4000. #ifdef _SC_MQ_OPEN_MAX
  4001.     {"SC_MQ_OPEN_MAX",    _SC_MQ_OPEN_MAX},
  4002. #endif
  4003. #ifdef _SC_MQ_PRIO_MAX
  4004.     {"SC_MQ_PRIO_MAX",    _SC_MQ_PRIO_MAX},
  4005. #endif
  4006. #ifdef _SC_NACLS_MAX
  4007.     {"SC_NACLS_MAX",    _SC_NACLS_MAX},
  4008. #endif
  4009. #ifdef _SC_NGROUPS_MAX
  4010.     {"SC_NGROUPS_MAX",    _SC_NGROUPS_MAX},
  4011. #endif
  4012. #ifdef _SC_NL_ARGMAX
  4013.     {"SC_NL_ARGMAX",    _SC_NL_ARGMAX},
  4014. #endif
  4015. #ifdef _SC_NL_LANGMAX
  4016.     {"SC_NL_LANGMAX",    _SC_NL_LANGMAX},
  4017. #endif
  4018. #ifdef _SC_NL_MSGMAX
  4019.     {"SC_NL_MSGMAX",    _SC_NL_MSGMAX},
  4020. #endif
  4021. #ifdef _SC_NL_NMAX
  4022.     {"SC_NL_NMAX",    _SC_NL_NMAX},
  4023. #endif
  4024. #ifdef _SC_NL_SETMAX
  4025.     {"SC_NL_SETMAX",    _SC_NL_SETMAX},
  4026. #endif
  4027. #ifdef _SC_NL_TEXTMAX
  4028.     {"SC_NL_TEXTMAX",    _SC_NL_TEXTMAX},
  4029. #endif
  4030. #ifdef _SC_NPROCESSORS_CONF
  4031.     {"SC_NPROCESSORS_CONF",    _SC_NPROCESSORS_CONF},
  4032. #endif
  4033. #ifdef _SC_NPROCESSORS_ONLN
  4034.     {"SC_NPROCESSORS_ONLN",    _SC_NPROCESSORS_ONLN},
  4035. #endif
  4036. #ifdef _SC_NPROC_CONF
  4037.     {"SC_NPROC_CONF",    _SC_NPROC_CONF},
  4038. #endif
  4039. #ifdef _SC_NPROC_ONLN
  4040.     {"SC_NPROC_ONLN",    _SC_NPROC_ONLN},
  4041. #endif
  4042. #ifdef _SC_NZERO
  4043.     {"SC_NZERO",    _SC_NZERO},
  4044. #endif
  4045. #ifdef _SC_OPEN_MAX
  4046.     {"SC_OPEN_MAX",    _SC_OPEN_MAX},
  4047. #endif
  4048. #ifdef _SC_PAGESIZE
  4049.     {"SC_PAGESIZE",    _SC_PAGESIZE},
  4050. #endif
  4051. #ifdef _SC_PAGE_SIZE
  4052.     {"SC_PAGE_SIZE",    _SC_PAGE_SIZE},
  4053. #endif
  4054. #ifdef _SC_PASS_MAX
  4055.     {"SC_PASS_MAX",    _SC_PASS_MAX},
  4056. #endif
  4057. #ifdef _SC_PHYS_PAGES
  4058.     {"SC_PHYS_PAGES",    _SC_PHYS_PAGES},
  4059. #endif
  4060. #ifdef _SC_PII
  4061.     {"SC_PII",    _SC_PII},
  4062. #endif
  4063. #ifdef _SC_PII_INTERNET
  4064.     {"SC_PII_INTERNET",    _SC_PII_INTERNET},
  4065. #endif
  4066. #ifdef _SC_PII_INTERNET_DGRAM
  4067.     {"SC_PII_INTERNET_DGRAM",    _SC_PII_INTERNET_DGRAM},
  4068. #endif
  4069. #ifdef _SC_PII_INTERNET_STREAM
  4070.     {"SC_PII_INTERNET_STREAM",    _SC_PII_INTERNET_STREAM},
  4071. #endif
  4072. #ifdef _SC_PII_OSI
  4073.     {"SC_PII_OSI",    _SC_PII_OSI},
  4074. #endif
  4075. #ifdef _SC_PII_OSI_CLTS
  4076.     {"SC_PII_OSI_CLTS",    _SC_PII_OSI_CLTS},
  4077. #endif
  4078. #ifdef _SC_PII_OSI_COTS
  4079.     {"SC_PII_OSI_COTS",    _SC_PII_OSI_COTS},
  4080. #endif
  4081. #ifdef _SC_PII_OSI_M
  4082.     {"SC_PII_OSI_M",    _SC_PII_OSI_M},
  4083. #endif
  4084. #ifdef _SC_PII_SOCKET
  4085.     {"SC_PII_SOCKET",    _SC_PII_SOCKET},
  4086. #endif
  4087. #ifdef _SC_PII_XTI
  4088.     {"SC_PII_XTI",    _SC_PII_XTI},
  4089. #endif
  4090. #ifdef _SC_POLL
  4091.     {"SC_POLL",    _SC_POLL},
  4092. #endif
  4093. #ifdef _SC_PRIORITIZED_IO
  4094.     {"SC_PRIORITIZED_IO",    _SC_PRIORITIZED_IO},
  4095. #endif
  4096. #ifdef _SC_PRIORITY_SCHEDULING
  4097.     {"SC_PRIORITY_SCHEDULING",    _SC_PRIORITY_SCHEDULING},
  4098. #endif
  4099. #ifdef _SC_REALTIME_SIGNALS
  4100.     {"SC_REALTIME_SIGNALS",    _SC_REALTIME_SIGNALS},
  4101. #endif
  4102. #ifdef _SC_RE_DUP_MAX
  4103.     {"SC_RE_DUP_MAX",    _SC_RE_DUP_MAX},
  4104. #endif
  4105. #ifdef _SC_RTSIG_MAX
  4106.     {"SC_RTSIG_MAX",    _SC_RTSIG_MAX},
  4107. #endif
  4108. #ifdef _SC_SAVED_IDS
  4109.     {"SC_SAVED_IDS",    _SC_SAVED_IDS},
  4110. #endif
  4111. #ifdef _SC_SCHAR_MAX
  4112.     {"SC_SCHAR_MAX",    _SC_SCHAR_MAX},
  4113. #endif
  4114. #ifdef _SC_SCHAR_MIN
  4115.     {"SC_SCHAR_MIN",    _SC_SCHAR_MIN},
  4116. #endif
  4117. #ifdef _SC_SELECT
  4118.     {"SC_SELECT",    _SC_SELECT},
  4119. #endif
  4120. #ifdef _SC_SEMAPHORES
  4121.     {"SC_SEMAPHORES",    _SC_SEMAPHORES},
  4122. #endif
  4123. #ifdef _SC_SEM_NSEMS_MAX
  4124.     {"SC_SEM_NSEMS_MAX",    _SC_SEM_NSEMS_MAX},
  4125. #endif
  4126. #ifdef _SC_SEM_VALUE_MAX
  4127.     {"SC_SEM_VALUE_MAX",    _SC_SEM_VALUE_MAX},
  4128. #endif
  4129. #ifdef _SC_SHARED_MEMORY_OBJECTS
  4130.     {"SC_SHARED_MEMORY_OBJECTS",    _SC_SHARED_MEMORY_OBJECTS},
  4131. #endif
  4132. #ifdef _SC_SHRT_MAX
  4133.     {"SC_SHRT_MAX",    _SC_SHRT_MAX},
  4134. #endif
  4135. #ifdef _SC_SHRT_MIN
  4136.     {"SC_SHRT_MIN",    _SC_SHRT_MIN},
  4137. #endif
  4138. #ifdef _SC_SIGQUEUE_MAX
  4139.     {"SC_SIGQUEUE_MAX",    _SC_SIGQUEUE_MAX},
  4140. #endif
  4141. #ifdef _SC_SIGRT_MAX
  4142.     {"SC_SIGRT_MAX",    _SC_SIGRT_MAX},
  4143. #endif
  4144. #ifdef _SC_SIGRT_MIN
  4145.     {"SC_SIGRT_MIN",    _SC_SIGRT_MIN},
  4146. #endif
  4147. #ifdef _SC_SOFTPOWER
  4148.     {"SC_SOFTPOWER",    _SC_SOFTPOWER},
  4149. #endif
  4150. #ifdef _SC_SPLIT_CACHE
  4151.     {"SC_SPLIT_CACHE",    _SC_SPLIT_CACHE},
  4152. #endif
  4153. #ifdef _SC_SSIZE_MAX
  4154.     {"SC_SSIZE_MAX",    _SC_SSIZE_MAX},
  4155. #endif
  4156. #ifdef _SC_STACK_PROT
  4157.     {"SC_STACK_PROT",    _SC_STACK_PROT},
  4158. #endif
  4159. #ifdef _SC_STREAM_MAX
  4160.     {"SC_STREAM_MAX",    _SC_STREAM_MAX},
  4161. #endif
  4162. #ifdef _SC_SYNCHRONIZED_IO
  4163.     {"SC_SYNCHRONIZED_IO",    _SC_SYNCHRONIZED_IO},
  4164. #endif
  4165. #ifdef _SC_THREADS
  4166.     {"SC_THREADS",    _SC_THREADS},
  4167. #endif
  4168. #ifdef _SC_THREAD_ATTR_STACKADDR
  4169.     {"SC_THREAD_ATTR_STACKADDR",    _SC_THREAD_ATTR_STACKADDR},
  4170. #endif
  4171. #ifdef _SC_THREAD_ATTR_STACKSIZE
  4172.     {"SC_THREAD_ATTR_STACKSIZE",    _SC_THREAD_ATTR_STACKSIZE},
  4173. #endif
  4174. #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
  4175.     {"SC_THREAD_DESTRUCTOR_ITERATIONS",    _SC_THREAD_DESTRUCTOR_ITERATIONS},
  4176. #endif
  4177. #ifdef _SC_THREAD_KEYS_MAX
  4178.     {"SC_THREAD_KEYS_MAX",    _SC_THREAD_KEYS_MAX},
  4179. #endif
  4180. #ifdef _SC_THREAD_PRIORITY_SCHEDULING
  4181.     {"SC_THREAD_PRIORITY_SCHEDULING",    _SC_THREAD_PRIORITY_SCHEDULING},
  4182. #endif
  4183. #ifdef _SC_THREAD_PRIO_INHERIT
  4184.     {"SC_THREAD_PRIO_INHERIT",    _SC_THREAD_PRIO_INHERIT},
  4185. #endif
  4186. #ifdef _SC_THREAD_PRIO_PROTECT
  4187.     {"SC_THREAD_PRIO_PROTECT",    _SC_THREAD_PRIO_PROTECT},
  4188. #endif
  4189. #ifdef _SC_THREAD_PROCESS_SHARED
  4190.     {"SC_THREAD_PROCESS_SHARED",    _SC_THREAD_PROCESS_SHARED},
  4191. #endif
  4192. #ifdef _SC_THREAD_SAFE_FUNCTIONS
  4193.     {"SC_THREAD_SAFE_FUNCTIONS",    _SC_THREAD_SAFE_FUNCTIONS},
  4194. #endif
  4195. #ifdef _SC_THREAD_STACK_MIN
  4196.     {"SC_THREAD_STACK_MIN",    _SC_THREAD_STACK_MIN},
  4197. #endif
  4198. #ifdef _SC_THREAD_THREADS_MAX
  4199.     {"SC_THREAD_THREADS_MAX",    _SC_THREAD_THREADS_MAX},
  4200. #endif
  4201. #ifdef _SC_TIMERS
  4202.     {"SC_TIMERS",    _SC_TIMERS},
  4203. #endif
  4204. #ifdef _SC_TIMER_MAX
  4205.     {"SC_TIMER_MAX",    _SC_TIMER_MAX},
  4206. #endif
  4207. #ifdef _SC_TTY_NAME_MAX
  4208.     {"SC_TTY_NAME_MAX",    _SC_TTY_NAME_MAX},
  4209. #endif
  4210. #ifdef _SC_TZNAME_MAX
  4211.     {"SC_TZNAME_MAX",    _SC_TZNAME_MAX},
  4212. #endif
  4213. #ifdef _SC_T_IOV_MAX
  4214.     {"SC_T_IOV_MAX",    _SC_T_IOV_MAX},
  4215. #endif
  4216. #ifdef _SC_UCHAR_MAX
  4217.     {"SC_UCHAR_MAX",    _SC_UCHAR_MAX},
  4218. #endif
  4219. #ifdef _SC_UINT_MAX
  4220.     {"SC_UINT_MAX",    _SC_UINT_MAX},
  4221. #endif
  4222. #ifdef _SC_UIO_MAXIOV
  4223.     {"SC_UIO_MAXIOV",    _SC_UIO_MAXIOV},
  4224. #endif
  4225. #ifdef _SC_ULONG_MAX
  4226.     {"SC_ULONG_MAX",    _SC_ULONG_MAX},
  4227. #endif
  4228. #ifdef _SC_USHRT_MAX
  4229.     {"SC_USHRT_MAX",    _SC_USHRT_MAX},
  4230. #endif
  4231. #ifdef _SC_VERSION
  4232.     {"SC_VERSION",    _SC_VERSION},
  4233. #endif
  4234. #ifdef _SC_WORD_BIT
  4235.     {"SC_WORD_BIT",    _SC_WORD_BIT},
  4236. #endif
  4237. #ifdef _SC_XBS5_ILP32_OFF32
  4238.     {"SC_XBS5_ILP32_OFF32",    _SC_XBS5_ILP32_OFF32},
  4239. #endif
  4240. #ifdef _SC_XBS5_ILP32_OFFBIG
  4241.     {"SC_XBS5_ILP32_OFFBIG",    _SC_XBS5_ILP32_OFFBIG},
  4242. #endif
  4243. #ifdef _SC_XBS5_LP64_OFF64
  4244.     {"SC_XBS5_LP64_OFF64",    _SC_XBS5_LP64_OFF64},
  4245. #endif
  4246. #ifdef _SC_XBS5_LPBIG_OFFBIG
  4247.     {"SC_XBS5_LPBIG_OFFBIG",    _SC_XBS5_LPBIG_OFFBIG},
  4248. #endif
  4249. #ifdef _SC_XOPEN_CRYPT
  4250.     {"SC_XOPEN_CRYPT",    _SC_XOPEN_CRYPT},
  4251. #endif
  4252. #ifdef _SC_XOPEN_ENH_I18N
  4253.     {"SC_XOPEN_ENH_I18N",    _SC_XOPEN_ENH_I18N},
  4254. #endif
  4255. #ifdef _SC_XOPEN_LEGACY
  4256.     {"SC_XOPEN_LEGACY",    _SC_XOPEN_LEGACY},
  4257. #endif
  4258. #ifdef _SC_XOPEN_REALTIME
  4259.     {"SC_XOPEN_REALTIME",    _SC_XOPEN_REALTIME},
  4260. #endif
  4261. #ifdef _SC_XOPEN_REALTIME_THREADS
  4262.     {"SC_XOPEN_REALTIME_THREADS",    _SC_XOPEN_REALTIME_THREADS},
  4263. #endif
  4264. #ifdef _SC_XOPEN_SHM
  4265.     {"SC_XOPEN_SHM",    _SC_XOPEN_SHM},
  4266. #endif
  4267. #ifdef _SC_XOPEN_UNIX
  4268.     {"SC_XOPEN_UNIX",    _SC_XOPEN_UNIX},
  4269. #endif
  4270. #ifdef _SC_XOPEN_VERSION
  4271.     {"SC_XOPEN_VERSION",    _SC_XOPEN_VERSION},
  4272. #endif
  4273. #ifdef _SC_XOPEN_XCU_VERSION
  4274.     {"SC_XOPEN_XCU_VERSION",    _SC_XOPEN_XCU_VERSION},
  4275. #endif
  4276. #ifdef _SC_XOPEN_XPG2
  4277.     {"SC_XOPEN_XPG2",    _SC_XOPEN_XPG2},
  4278. #endif
  4279. #ifdef _SC_XOPEN_XPG3
  4280.     {"SC_XOPEN_XPG3",    _SC_XOPEN_XPG3},
  4281. #endif
  4282. #ifdef _SC_XOPEN_XPG4
  4283.     {"SC_XOPEN_XPG4",    _SC_XOPEN_XPG4},
  4284. #endif
  4285. };
  4286.  
  4287. static int
  4288. conv_sysconf_confname(arg, valuep)
  4289.      PyObject *arg;
  4290.      int *valuep;
  4291. {
  4292.     return conv_confname(arg, valuep, posix_constants_sysconf,
  4293.                          sizeof(posix_constants_sysconf)
  4294.                            / sizeof(struct constdef));
  4295. }
  4296.  
  4297. static char posix_sysconf__doc__[] = "\
  4298. sysconf(name) -> integer\n\
  4299. Return an integer-valued system configuration variable.";
  4300.  
  4301. static PyObject *
  4302. posix_sysconf(self, args)
  4303.      PyObject *self;
  4304.      PyObject *args;
  4305. {
  4306.     PyObject *result = NULL;
  4307.     int name;
  4308.  
  4309.     if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
  4310.         int value;
  4311.  
  4312.         errno = 0;
  4313.         value = sysconf(name);
  4314.         if (value == -1 && errno != 0)
  4315.             posix_error();
  4316.         else
  4317.             result = PyInt_FromLong(value);
  4318.     }
  4319.     return result;
  4320. }
  4321. #endif
  4322.  
  4323.  
  4324. /* This code is used to ensure that the tables of configuration value names
  4325.  * are in sorted order as required by conv_confname(), and also to build the
  4326.  * the exported dictionaries that are used to publish information about the
  4327.  * names available on the host platform.
  4328.  *
  4329.  * Sorting the table at runtime ensures that the table is properly ordered
  4330.  * when used, even for platforms we're not able to test on.  It also makes
  4331.  * it easier to add additional entries to the tables.
  4332.  */
  4333.  
  4334. static int
  4335. cmp_constdefs(v1, v2)
  4336.      const void *v1;
  4337.      const void *v2;
  4338. {
  4339.     const struct constdef *c1 =
  4340.         (const struct constdef *) v1;
  4341.     const struct constdef *c2 =
  4342.         (const struct constdef *) v2;
  4343.  
  4344.     return strcmp(c1->name, c2->name);
  4345. }
  4346.  
  4347. static int
  4348. setup_confname_table(table, tablesize, tablename, moddict)
  4349.      struct constdef *table;
  4350.      size_t tablesize;
  4351.      char * tablename;
  4352.      PyObject *moddict;
  4353. {
  4354.     PyObject *d = NULL;
  4355.     size_t i;
  4356.     int status;
  4357.  
  4358.     qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
  4359.     d = PyDict_New();
  4360.     if (d == NULL)
  4361.         return -1;
  4362.  
  4363.     for (i=0; i < tablesize; ++i) {
  4364.             PyObject *o = PyInt_FromLong(table[i].value);
  4365.             if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
  4366.             Py_XDECREF(o);
  4367.             Py_DECREF(d);
  4368.             return -1;
  4369.             }
  4370.         Py_DECREF(o);
  4371.     }
  4372.     status = PyDict_SetItemString(moddict, tablename, d);
  4373.     Py_DECREF(d);
  4374.     return status;
  4375. }
  4376.  
  4377. /* Return -1 on failure, 0 on success. */
  4378. static int
  4379. setup_confname_tables(moddict)
  4380.      PyObject *moddict;
  4381. {
  4382. #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
  4383.     if (setup_confname_table(posix_constants_pathconf,
  4384.                              sizeof(posix_constants_pathconf)
  4385.                                / sizeof(struct constdef),
  4386.                              "pathconf_names", moddict))
  4387.         return -1;
  4388. #endif
  4389. #ifdef HAVE_CONFSTR
  4390.     if (setup_confname_table(posix_constants_confstr,
  4391.                              sizeof(posix_constants_confstr)
  4392.                                / sizeof(struct constdef),
  4393.                              "confstr_names", moddict))
  4394.         return -1;
  4395. #endif
  4396. #ifdef HAVE_SYSCONF
  4397.     if (setup_confname_table(posix_constants_sysconf,
  4398.                              sizeof(posix_constants_sysconf)
  4399.                                / sizeof(struct constdef),
  4400.                              "sysconf_names", moddict))
  4401.         return -1;
  4402. #endif
  4403.     return 0;
  4404. }
  4405.  
  4406.  
  4407. static char posix_abort__doc__[] = "\
  4408. abort() -> does not return!\n\
  4409. Abort the interpreter immediately.  This 'dumps core' or otherwise fails\n\
  4410. in the hardest way possible on the hosting operating system.";
  4411.  
  4412. static PyObject *
  4413. posix_abort(self, args)
  4414.      PyObject *self;
  4415.      PyObject *args;
  4416. {
  4417.     if (!PyArg_ParseTuple(args, ":abort"))
  4418.         return NULL;
  4419.     abort();
  4420.     /*NOTREACHED*/
  4421.     Py_FatalError("abort() called from Python code didn't abort!");
  4422.     return NULL;
  4423. }
  4424.  
  4425.  
  4426. static PyMethodDef posix_methods[] = {
  4427.     {"access",    posix_access, METH_VARARGS, posix_access__doc__},
  4428. #ifdef HAVE_TTYNAME
  4429.     {"ttyname",    posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
  4430. #endif
  4431.     {"chdir",    posix_chdir, METH_VARARGS, posix_chdir__doc__},
  4432.     {"chmod",    posix_chmod, METH_VARARGS, posix_chmod__doc__},
  4433. #ifdef HAVE_CHOWN
  4434.     {"chown",    posix_chown, METH_VARARGS, posix_chown__doc__},
  4435. #endif /* HAVE_CHOWN */
  4436. #ifdef HAVE_CTERMID
  4437.     {"ctermid",    posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
  4438. #endif
  4439. #ifdef HAVE_GETCWD
  4440.     {"getcwd",    posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
  4441. #endif
  4442. #ifdef HAVE_LINK
  4443.     {"link",    posix_link, METH_VARARGS, posix_link__doc__},
  4444. #endif /* HAVE_LINK */
  4445.     {"listdir",    posix_listdir, METH_VARARGS, posix_listdir__doc__},
  4446.     {"lstat",    posix_lstat, METH_VARARGS, posix_lstat__doc__},
  4447.     {"mkdir",    posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
  4448. #ifdef HAVE_NICE
  4449.     {"nice",    posix_nice, METH_VARARGS, posix_nice__doc__},
  4450. #endif /* HAVE_NICE */
  4451. #ifdef HAVE_READLINK
  4452.     {"readlink",    posix_readlink, METH_VARARGS, posix_readlink__doc__},
  4453. #endif /* HAVE_READLINK */
  4454.     {"rename",    posix_rename, METH_VARARGS, posix_rename__doc__},
  4455.     {"rmdir",    posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
  4456.     {"stat",    posix_stat, METH_VARARGS, posix_stat__doc__},
  4457. #ifdef HAVE_SYMLINK
  4458.     {"symlink",    posix_symlink, METH_VARARGS, posix_symlink__doc__},
  4459. #endif /* HAVE_SYMLINK */
  4460. #ifdef HAVE_SYSTEM
  4461.     {"system",    posix_system, METH_VARARGS, posix_system__doc__},
  4462. #endif
  4463.     {"umask",    posix_umask, METH_VARARGS, posix_umask__doc__},
  4464. #ifdef HAVE_UNAME
  4465.     {"uname",    posix_uname, METH_VARARGS, posix_uname__doc__},
  4466. #endif /* HAVE_UNAME */
  4467.     {"unlink",    posix_unlink, METH_VARARGS, posix_unlink__doc__},
  4468.     {"remove",    posix_unlink, METH_VARARGS, posix_remove__doc__},
  4469.     {"utime",    posix_utime, METH_VARARGS, posix_utime__doc__},
  4470. #ifdef HAVE_TIMES
  4471.     {"times",    posix_times, METH_VARARGS, posix_times__doc__},
  4472. #endif /* HAVE_TIMES */
  4473.     {"_exit",    posix__exit, METH_VARARGS, posix__exit__doc__},
  4474. #ifdef HAVE_EXECV
  4475.     {"execv",    posix_execv, METH_VARARGS, posix_execv__doc__},
  4476.     {"execve",    posix_execve, METH_VARARGS, posix_execve__doc__},
  4477. #endif /* HAVE_EXECV */
  4478. #ifdef HAVE_SPAWNV
  4479.     {"spawnv",    posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
  4480.     {"spawnve",    posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
  4481. #endif /* HAVE_SPAWNV */
  4482. #ifdef HAVE_FORK
  4483.     {"fork",    posix_fork, METH_VARARGS, posix_fork__doc__},
  4484. #endif /* HAVE_FORK */
  4485. #ifdef HAVE_GETEGID
  4486.     {"getegid",    posix_getegid, METH_VARARGS, posix_getegid__doc__},
  4487. #endif /* HAVE_GETEGID */
  4488. #ifdef HAVE_GETEUID
  4489.     {"geteuid",    posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
  4490. #endif /* HAVE_GETEUID */
  4491. #ifdef HAVE_GETGID
  4492.     {"getgid",    posix_getgid, METH_VARARGS, posix_getgid__doc__},
  4493. #endif /* HAVE_GETGID */
  4494. #ifdef HAVE_GETGROUPS
  4495.     {"getgroups",    posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
  4496. #endif
  4497.     {"getpid",    posix_getpid, METH_VARARGS, posix_getpid__doc__},
  4498. #ifdef HAVE_GETPGRP
  4499.     {"getpgrp",    posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
  4500. #endif /* HAVE_GETPGRP */
  4501. #ifdef HAVE_GETPPID
  4502.     {"getppid",    posix_getppid, METH_VARARGS, posix_getppid__doc__},
  4503. #endif /* HAVE_GETPPID */
  4504. #ifdef HAVE_GETUID
  4505.     {"getuid",    posix_getuid, METH_VARARGS, posix_getuid__doc__},
  4506. #endif /* HAVE_GETUID */
  4507. #ifdef HAVE_GETLOGIN
  4508.     {"getlogin",    posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
  4509. #endif
  4510. #ifdef HAVE_KILL
  4511.     {"kill",    posix_kill, METH_VARARGS, posix_kill__doc__},
  4512. #endif /* HAVE_KILL */
  4513. #ifdef HAVE_PLOCK
  4514.     {"plock",    posix_plock, METH_VARARGS, posix_plock__doc__},
  4515. #endif /* HAVE_PLOCK */
  4516. #ifdef HAVE_POPEN
  4517.     {"popen",    posix_popen, METH_VARARGS, posix_popen__doc__},
  4518. #endif /* HAVE_POPEN */
  4519. #ifdef HAVE_SETUID
  4520.     {"setuid",    posix_setuid, METH_VARARGS, posix_setuid__doc__},
  4521. #endif /* HAVE_SETUID */
  4522. #ifdef HAVE_SETGID
  4523.     {"setgid",    posix_setgid, METH_VARARGS, posix_setgid__doc__},
  4524. #endif /* HAVE_SETGID */
  4525. #ifdef HAVE_SETPGRP
  4526.     {"setpgrp",    posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
  4527. #endif /* HAVE_SETPGRP */
  4528. #ifdef HAVE_WAIT
  4529.     {"wait",    posix_wait, METH_VARARGS, posix_wait__doc__},
  4530. #endif /* HAVE_WAIT */
  4531. #ifdef HAVE_WAITPID
  4532.     {"waitpid",    posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
  4533. #endif /* HAVE_WAITPID */
  4534. #ifdef HAVE_SETSID
  4535.     {"setsid",    posix_setsid, METH_VARARGS, posix_setsid__doc__},
  4536. #endif /* HAVE_SETSID */
  4537. #ifdef HAVE_SETPGID
  4538.     {"setpgid",    posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
  4539. #endif /* HAVE_SETPGID */
  4540. #ifdef HAVE_TCGETPGRP
  4541.     {"tcgetpgrp",    posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
  4542. #endif /* HAVE_TCGETPGRP */
  4543. #ifdef HAVE_TCSETPGRP
  4544.     {"tcsetpgrp",    posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
  4545. #endif /* HAVE_TCSETPGRP */
  4546.     {"open",    posix_open, METH_VARARGS, posix_open__doc__},
  4547.     {"close",    posix_close, METH_VARARGS, posix_close__doc__},
  4548.     {"dup",        posix_dup, METH_VARARGS, posix_dup__doc__},
  4549.     {"dup2",    posix_dup2, METH_VARARGS, posix_dup2__doc__},
  4550.     {"lseek",    posix_lseek, METH_VARARGS, posix_lseek__doc__},
  4551.     {"read",    posix_read, METH_VARARGS, posix_read__doc__},
  4552.     {"write",    posix_write, METH_VARARGS, posix_write__doc__},
  4553.     {"fstat",    posix_fstat, METH_VARARGS, posix_fstat__doc__},
  4554.     {"fdopen",    posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
  4555. #ifdef HAVE_PIPE
  4556.     {"pipe",    posix_pipe, METH_VARARGS, posix_pipe__doc__},
  4557. #endif
  4558. #ifdef HAVE_MKFIFO
  4559.     {"mkfifo",    posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
  4560. #endif
  4561. #ifdef HAVE_FTRUNCATE
  4562.     {"ftruncate",    posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
  4563. #endif
  4564. #ifdef HAVE_PUTENV
  4565.     {"putenv",    posix_putenv, METH_VARARGS, posix_putenv__doc__},
  4566. #endif
  4567. #ifdef HAVE_STRERROR
  4568.     {"strerror",    posix_strerror, METH_VARARGS, posix_strerror__doc__},
  4569. #endif
  4570. #ifdef HAVE_FSYNC
  4571.     {"fsync",       posix_fsync, METH_VARARGS, posix_fsync__doc__},
  4572. #endif
  4573. #ifdef HAVE_FDATASYNC
  4574.     {"fdatasync",   posix_fdatasync,  METH_VARARGS, posix_fdatasync__doc__},
  4575. #endif
  4576. #ifdef HAVE_SYS_WAIT_H
  4577. #ifdef WIFSTOPPED
  4578.         {"WIFSTOPPED",    posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
  4579. #endif /* WIFSTOPPED */
  4580. #ifdef WIFSIGNALED
  4581.         {"WIFSIGNALED",    posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
  4582. #endif /* WIFSIGNALED */
  4583. #ifdef WIFEXITED
  4584.         {"WIFEXITED",    posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
  4585. #endif /* WIFEXITED */
  4586. #ifdef WEXITSTATUS
  4587.         {"WEXITSTATUS",    posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
  4588. #endif /* WEXITSTATUS */
  4589. #ifdef WTERMSIG
  4590.         {"WTERMSIG",    posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
  4591. #endif /* WTERMSIG */
  4592. #ifdef WSTOPSIG
  4593.         {"WSTOPSIG",    posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
  4594. #endif /* WSTOPSIG */
  4595. #endif /* HAVE_SYS_WAIT_H */
  4596. #ifdef HAVE_FSTATVFS
  4597.     {"fstatvfs",    posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
  4598. #endif
  4599. #ifdef HAVE_STATVFS
  4600.     {"statvfs",    posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
  4601. #endif
  4602. #ifdef HAVE_TMPNAM
  4603.     {"tmpfile",    posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
  4604. #endif
  4605. #ifdef HAVE_TEMPNAM
  4606.     {"tempnam",    posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
  4607. #endif
  4608. #ifdef HAVE_TMPNAM
  4609.     {"tmpnam",    posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
  4610. #endif
  4611. #ifdef HAVE_CONFSTR
  4612.     {"confstr",    posix_confstr, METH_VARARGS, posix_confstr__doc__},
  4613. #endif
  4614. #ifdef HAVE_SYSCONF
  4615.     {"sysconf",    posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
  4616. #endif
  4617. #ifdef HAVE_FPATHCONF
  4618.     {"fpathconf",    posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
  4619. #endif
  4620. #ifdef HAVE_PATHCONF
  4621.     {"pathconf",    posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
  4622. #endif
  4623.     {"abort",    posix_abort, METH_VARARGS, posix_abort__doc__},
  4624.     {NULL,        NULL}         /* Sentinel */
  4625. };
  4626.  
  4627.  
  4628. static int
  4629. ins(d, symbol, value)
  4630.         PyObject* d;
  4631.         char* symbol;
  4632.         long value;
  4633. {
  4634.         PyObject* v = PyInt_FromLong(value);
  4635.         if (!v || PyDict_SetItemString(d, symbol, v) < 0)
  4636.                 return -1;                   /* triggers fatal error */
  4637.  
  4638.         Py_DECREF(v);
  4639.         return 0;
  4640. }
  4641.  
  4642. #if defined(PYOS_OS2)
  4643. /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
  4644. static int insertvalues(PyObject *d)
  4645. {
  4646.     APIRET    rc;
  4647.     ULONG     values[QSV_MAX+1];
  4648.     PyObject *v;
  4649.     char     *ver, tmp[10];
  4650.  
  4651.     Py_BEGIN_ALLOW_THREADS
  4652.     rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
  4653.     Py_END_ALLOW_THREADS
  4654.  
  4655.     if (rc != NO_ERROR) {
  4656.         os2_error(rc);
  4657.         return -1;
  4658.     }
  4659.  
  4660.     if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
  4661.     if (ins(d, "memkernel",    values[QSV_TOTRESMEM])) return -1;
  4662.     if (ins(d, "memvirtual",   values[QSV_TOTAVAILMEM])) return -1;
  4663.     if (ins(d, "maxpathlen",   values[QSV_MAX_PATH_LENGTH])) return -1;
  4664.     if (ins(d, "maxnamelen",   values[QSV_MAX_COMP_LENGTH])) return -1;
  4665.     if (ins(d, "revision",     values[QSV_VERSION_REVISION])) return -1;
  4666.     if (ins(d, "timeslice",    values[QSV_MIN_SLICE])) return -1;
  4667.  
  4668.     switch (values[QSV_VERSION_MINOR]) {
  4669.     case 0:  ver = "2.00"; break;
  4670.     case 10: ver = "2.10"; break;
  4671.     case 11: ver = "2.11"; break;
  4672.     case 30: ver = "3.00"; break;
  4673.     case 40: ver = "4.00"; break;
  4674.     case 50: ver = "5.00"; break;
  4675.     default:
  4676.         sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
  4677.                               values[QSV_VERSION_MINOR]);
  4678.         ver = &tmp[0];
  4679.     }
  4680.  
  4681.     /* Add Indicator of the Version of the Operating System */
  4682.     v = PyString_FromString(ver);
  4683.     if (!v || PyDict_SetItemString(d, "version", v) < 0)
  4684.         return -1;
  4685.     Py_DECREF(v);
  4686.  
  4687.     /* Add Indicator of Which Drive was Used to Boot the System */
  4688.     tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
  4689.     tmp[1] = ':';
  4690.     tmp[2] = '\0';
  4691.  
  4692.     v = PyString_FromString(tmp);
  4693.     if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
  4694.         return -1;
  4695.     Py_DECREF(v);
  4696.  
  4697.     return 0;
  4698. }
  4699. #endif
  4700.  
  4701. static int
  4702. all_ins(d)
  4703.         PyObject* d;
  4704. {
  4705. #ifdef F_OK
  4706.         if (ins(d, "F_OK", (long)F_OK)) return -1;
  4707. #endif        
  4708. #ifdef R_OK
  4709.         if (ins(d, "R_OK", (long)R_OK)) return -1;
  4710. #endif        
  4711. #ifdef W_OK
  4712.         if (ins(d, "W_OK", (long)W_OK)) return -1;
  4713. #endif        
  4714. #ifdef X_OK
  4715.         if (ins(d, "X_OK", (long)X_OK)) return -1;
  4716. #endif        
  4717. #ifdef NGROUPS_MAX
  4718.         if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
  4719. #endif
  4720. #ifdef TMP_MAX
  4721.         if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
  4722. #endif
  4723. #ifdef WNOHANG
  4724.         if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
  4725. #endif        
  4726. #ifdef O_RDONLY
  4727.         if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
  4728. #endif
  4729. #ifdef O_WRONLY
  4730.         if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
  4731. #endif
  4732. #ifdef O_RDWR
  4733.         if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
  4734. #endif
  4735. #ifdef O_NDELAY
  4736.         if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
  4737. #endif
  4738. #ifdef O_NONBLOCK
  4739.         if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
  4740. #endif
  4741. #ifdef O_APPEND
  4742.         if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
  4743. #endif
  4744. #ifdef O_DSYNC
  4745.         if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
  4746. #endif
  4747. #ifdef O_RSYNC
  4748.         if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
  4749. #endif
  4750. #ifdef O_SYNC
  4751.         if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
  4752. #endif
  4753. #ifdef O_NOCTTY
  4754.         if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
  4755. #endif
  4756. #ifdef O_CREAT
  4757.         if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
  4758. #endif
  4759. #ifdef O_EXCL
  4760.         if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
  4761. #endif
  4762. #ifdef O_TRUNC
  4763.         if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
  4764. #endif
  4765. #ifdef O_BINARY
  4766.         if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
  4767. #endif
  4768. #ifdef O_TEXT
  4769.         if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
  4770. #endif
  4771.  
  4772. #ifdef HAVE_SPAWNV
  4773.         if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
  4774.         if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
  4775.         if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
  4776.         if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
  4777.         if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
  4778. #endif
  4779.  
  4780. #if defined(PYOS_OS2)
  4781.         if (insertvalues(d)) return -1;
  4782. #endif
  4783.         return 0;
  4784. }
  4785.  
  4786.  
  4787. #if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
  4788. #define INITFUNC initnt
  4789. #define MODNAME "nt"
  4790. #else
  4791. #if defined(PYOS_OS2)
  4792. #define INITFUNC initos2
  4793. #define MODNAME "os2"
  4794. #else
  4795. #define INITFUNC initposix
  4796. #define MODNAME "posix"
  4797. #endif
  4798. #endif
  4799.  
  4800. DL_EXPORT(void)
  4801. INITFUNC()
  4802. {
  4803.     PyObject *m, *d, *v;
  4804.     
  4805.     m = Py_InitModule4(MODNAME,
  4806.                posix_methods,
  4807.                posix__doc__,
  4808.                (PyObject *)NULL,
  4809.                PYTHON_API_VERSION);
  4810.     d = PyModule_GetDict(m);
  4811.     
  4812.     /* Initialize environ dictionary */
  4813.     v = convertenviron();
  4814.     if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
  4815.         return;
  4816.     Py_DECREF(v);
  4817.  
  4818.         if (all_ins(d))
  4819.                 return;
  4820.  
  4821.         if (setup_confname_tables(d))
  4822.                 return;
  4823.  
  4824.     PyDict_SetItemString(d, "error", PyExc_OSError);
  4825.  
  4826. #ifdef HAVE_PUTENV
  4827.     posix_putenv_garbage = PyDict_New();
  4828. #endif
  4829. }
  4830.